这是一个真正的谜.
想象一下,您正在进行在屏幕外绘制复杂图像的传统过程(CGLayer),并且您在绘制时间歇性地将图像更新到屏幕上.
如您所知,执行此操作的方法是:在后台运行大型绘图过程,并根据需要调用setNeedsDisplays的前景,从而更新图像.这是微不足道的,可以通过两行代码实现.
但是,当你这样做时,会出现一个神秘的问题:每个绘图周期所花费的时间,每次都会增加,变得无法使用.此外,时间可能不规律地变化.
这是一个已知的iOS错误,还是?谁看过这个吗?
这是一个非常简单,非常容易理解的应用程序,可以解决问题:
http://www.fileswap.com/dl/p8lU3gAi/stepwiseDrawingV2.zip.html
输出示例如下.
有谁知道为什么会这样?操作系统的行为非常奇怪.
后来 ...... FELZ已经找到了令人震惊的解决方案.Felz副本的CGLayer一次每一轮.这完全阻止了这种奇怪的行为.
然而,对于究竟发生了什么仍然没有真正清楚的理解:因此从字面上看,当奇怪的问题出现时,时间在哪里?
这是一个很长的输出示例......
请注意,您有时会得到一个"双重奇异"的结果,如下所示:它表现出"正常"奇怪的行为:每次都会增加时间.然而,偶尔会有几轮时间"非常快",然后返回.怪啊?此外,如果您在模拟器上运行,请快速单击Mac上不相关的应用程序,以获得"更奇怪"的结果.
尽管费尔兹给出了一个完美的工作答案,但实际的机制仍然是一个谜.
:26:56.697 stepwiseDrawing[5334:1a03] time difference was 0
:26:56.707 stepwiseDrawing[5334:1a03] time difference was 10
:26:56.717 stepwiseDrawing[5334:1a03] time difference was 10
:26:56.744 stepwiseDrawing[5334:1a03] time difference was 27
:26:56.771 stepwiseDrawing[5334:1a03] time difference was 27
:26:56.807 stepwiseDrawing[5334:1a03] time difference was 37
:26:56.829 stepwiseDrawing[5334:1a03] time difference was 22
:26:56.864 stepwiseDrawing[5334:1a03] time difference was 35
:26:56.891 stepwiseDrawing[5334:1a03] time difference was 28
:26:56.936 stepwiseDrawing[5334:1a03] time difference was 45 …Run Code Online (Sandbox Code Playgroud) 我试图drawRect:在我的自定义视图中覆盖UIView 的方法.但是,我的视图的边界半径定义为:
sub = [[[NSBundle mainBundle] loadNibNamed:@"ProfileView" owner:self options:nil] objectAtIndex:0];
[self addSubview:sub];
[sub setUserInteractionEnabled:YES];
[self setUserInteractionEnabled:YES];
CALayer *layer = sub.layer;
layer.masksToBounds = YES;
layer.borderWidth = 5.0;
layer.borderColor = [UIColor whiteColor].CGColor;
layer.cornerRadius = 30.0;
Run Code Online (Sandbox Code Playgroud)
这完美地工作,并在我的视图周围放置一个边框半径很好的边框(不要介意背面的对角线/直线白线,它们与此视图无关):

但是,当我尝试drawRect:在我的视图中覆盖该方法时,我可以看到黑色背景没有掩盖到边界.我没有做任何事情(目前),这里是我的代码:
-(void)drawRect:(CGRect)rect{
[super drawRect:rect];
}
Run Code Online (Sandbox Code Playgroud)
这是结果:

我只改变了绘制方法.如何在保持视图遵循角半径蒙版的同时覆盖绘制方法?这是iOS中的错误还是我错过了什么?
里面有一个UIView子类(ThumbView)UICollectionViewCell.以下代码在iOS 7模拟器中运行良好:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = @"Cell";
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
ThumbView *thumbView = (ThumbView *)[cell viewWithTag:1];
[thumbView setNeedsDisplay];
return cell;
}
Run Code Online (Sandbox Code Playgroud)

但是,在iOS 6版本的模拟器中:
网格都消失了:

我已经把NSLog在drawRect该ThumbView,以确保drawRect被调用.
怎么了?
更新(图纸代码):
- (void)drawRect:(CGRect)rect
{
NSLog(@"%s", __func__);
[self drawGrid:rect];
}
- (void)drawGrid:(CGRect)rect
{
CGFloat margin = self.margin;
CGFloat lineWidth = 2.0;
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect gridRect = CGRectInset(rect, margin, margin);
for …Run Code Online (Sandbox Code Playgroud) 我正在尝试创建一个子类UITableViewCell,我在右上角绘制一个图像.我有完美的工作 - 除非我设置self.backgroundView,我的背景图像掩盖了drawRect中绘制的图像.
必须有一种方法可以设置背景图像(和selectedBackgroundView),而不会掩盖drawRect中正在进行的操作.
我是以错误的方式来做这件事的吗?
编辑:我已经发布了一个问题示例项目.
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) {
// TODO: figure out why this covers up self.starImage that's drawn in drawRect
self.backgroundView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"cellBackground.png"]] autorelease];
}
return self;
}
- (void)drawRect:(CGRect)rect {
[self.starImage drawAtPoint:CGPointMake(self.bounds.size.width - self.starImage.size.width, 0.0)];
}
Run Code Online (Sandbox Code Playgroud)
编辑2:在AWrightIV的要求下,这是我如何工作...这根本不需要子类化UITableViewCell.我只是在cell.backgroundView中添加一个子视图:
// create a UIImageView that contains the background image for the cell
UIImageView *bgImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"cellBackground.png"]];
// create another UIImageView that contains the …Run Code Online (Sandbox Code Playgroud) UPDATE
通过使用OpenGL绘制所有内容,我克服了CG的局限性.还是有一些小故障,但到目前为止它工作得更快,更快.
一些有趣的观点:
GLKView:这是一个特定于iOS的视图,它在设置OpenGL上下文和渲染循环方面有很大帮助.如果你不在iOS上,我担心你是独自一人.GL_LINES:OpenGL ES可以原生地绘制简单的线条.不是很好(没有关节,没有帽子,请看下面屏幕截图顶部的紫色/灰色线条),但为了改善你必须编写一个自定义着色器,将每一行转换成三角形条并祈祷它作品!(据说当浏览器告诉你Canvas2D是GPU加速时,浏览器会这样做) 
原始问题
我正在尝试在drawRect滚动视图的方法中绘制大量CGPath(通常超过1000),当用户用手指平移时刷新.我在浏览器的JavaScript中使用相同的应用程序,我正在尝试将其移植到iOS本机应用程序.
iOS测试代码是(100行操作,path是预先制作的CGMutablePathRef):
- (void) drawRect:(CGRect)rect {
// Start the timer
BSInitClass(@"Renderer");
BSStartTimedOp(@"Rendering");
// Get the context
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 2.0);
CGContextSetFillColorWithColor(context, [[UIColor redColor] CGColor]);
CGContextSetStrokeColorWithColor(context, [[UIColor blueColor] CGColor]);
CGContextTranslateCTM(context, 800, 800);
// Draw the points
CGContextAddPath(context, path);
CGContextStrokePath(context);
// Display the elapsed time
BSEndTimedOp(@"Rendering"); …Run Code Online (Sandbox Code Playgroud) 我的应用程序能够做一些简单的图形绘制(直到我得到一个更稳定的代码,我只坚持一个图),它也能够重新调整它们的大小.我用来创建a的代码UIView如下:
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
[self setContextFillColor:context];
[self setContextStrokeColor:context];
[self setLineWidth:context];
CGFloat lineThickness = [self lineWidth] ;
CGFloat halfLineThickess = lineThickness / 2.0f;
CGContextAddRect(context, CGRectMake(halfLineThickess,halfLineThickess, rect.size.width - lineThickness, rect.size.height - lineThickness));
CGContextDrawPath(context, kCGPathEOFillStroke);
}
Run Code Online (Sandbox Code Playgroud)
这给了我,输入大小为(100.0f,100.0f),这个:

这个数字在一个"容器" UIView里面,而"容器" 又在里面UIScrollView.我的问题是当我重新调整我的身材并且我达到大约1000*1000的大小(我的"容器"是20,000*20,000)时,我开始接收内存警告并且应用程序最终放弃了.所以我的问题是:
1)我应该考虑为此设置最大尺寸UIView吗?
2)我怎样才能使用仪器来跟踪这类问题,看看问题出在哪里(或者在哪里进行繁重的工作).
3)我应该使用某种像缓存这样?
4)在绘制时,是否有一些一般的最佳实践需要考虑UIView?
5)我应该考虑一下CALayer,虽然我需要听一听吗?
重新调整大小UIView主要基于此.
下面的代码绘制了一个完美的椭圆径向渐变,但没有填充它的视角.如何让它超出椭圆的边缘?记录的选项是kCGGradientDrawsAfterEndLocation,但我认为它在ios中不可用.
- (void)drawRect:(CGRect)rect
{
CGFloat colors [] = {
0.2, 0.2, 0.2, 1.0,
0.0, 0.0, 0.0, 1.0
};
CGColorSpaceRef baseSpace = CGColorSpaceCreateDeviceRGB();
CGGradientRef gradient = CGGradientCreateWithColorComponents(baseSpace, colors, NULL, 2);
CGColorSpaceRelease(baseSpace), baseSpace = NULL;
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGContextAddEllipseInRect(context, rect);
CGContextClip(context);
CGContextDrawRadialGradient(context, gradient, self.center, 0, self.center, self.frame.size.width, kCGGradientDrawsAfterEndLocation);
CGGradientRelease(gradient), gradient = NULL;
CGContextRestoreGState(context);
}
Run Code Online (Sandbox Code Playgroud)

我想在我的自定义drawRect方法中检查我的自定义NSButton当前是否处于按下状态(用户正在点击它).像这样的东西:
- (void)drawRect:(NSRect)dirtyRect{
if ([self buttonIsInPressedState]) {
[[self alternateBGImage] drawInRect:dirtyRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0f];
}else{
[[self BGImage] drawInRect:dirtyRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0f];
}
[super drawRect:dirtyRect];
}
Run Code Online (Sandbox Code Playgroud)
你会怎么检查这样的事情?可能吗?
解
我最终检查了按钮单元格上的mouseDownFlags.不知道这是否是"正确"的方式,所以如果你有更好的建议,请告诉我:
- (void)drawRect:(NSRect)dirtyRect{
if ([self.cell mouseDownFlags] == 0) {
[[self BGImage] drawInRect:dirtyRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0f];
}else{
[[self alternateBGImage] drawInRect:dirtyRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0f];
}
[super drawRect:dirtyRect];
}
Run Code Online (Sandbox Code Playgroud) 我有一个viewController,它显然是UIViewController被调用的子类MapViewController.在这个viewController中,我使用GPS来获取用户的位置.
我也有一个叫做的观点DrawCircle.该视图是其子类UIView.
使用drawCircle我希望能够随时在我的MapViewController上绘图.但我不确定我是否理解这样做的概念.我知道我的绘图代码正在运行,我之前使用过它.但我不知道如何MapViewController使用DrawCircle.
从我看来,只要我打电话[myCustomView setNeedsDisplay],它就不会DrawRect在我看来调用方法.
这是一些代码: MapViewController.h
#import "DrawCircle.h"
@interface MapViewController: UIViewController <CLLocationManagerDelegate>{
DrawCircle *circleView;
}
@property (nonatomic, retain) DrawCircle *circleView;
@end
Run Code Online (Sandbox Code Playgroud)
MapViewController.m
#import "DrawCircle.h"
@interface MapViewController ()
@end
@implementation MapViewController
@synthesize circleView;
- (void) viewDidLoad
{
circleView = [[DrawCircle alloc] init];
[self setNeedsDisplay];
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
@end
Run Code Online (Sandbox Code Playgroud)
DrawCircle.m
#import "DrawCircle.h"
@interface DrawCircle()
@end
@implementation DrawCircle
-(id)initWithFrame:(CGRect)frame { …Run Code Online (Sandbox Code Playgroud) 我正在制作一个循环进度条,用于自定义游戏中心成就视图,我有点"碰壁".我正在为此奋斗超过两个小时仍然无法让它工作.
问题是,我需要一个循环进度条,在那里我可以设置(至少)轨道(填充)图像.因为我的进度填充是渐变的彩虹,我不能仅使用代码获得相同的结果.
我正在搞乱CALayers和drawRect方法,但是我没有成功.你能给我一点指导吗?
以下是循环进度条的示例:https : //github.com/donnellyk/KDGoalBar https://github.com/danielamitay/DACircularProgress
我只需要填充是一个蒙面图像,取决于进度.如果你甚至可以让它的工作进展动画,那真的很酷,但我不需要帮助:)
谢谢,尼克