原来的问题...............................................
如果您是drawRect的高级用户,您将知道当然"drawRect"在"所有处理完成"之前不会实际运行.
setNeedsDisplay将视图标记为无效和操作系统,并且基本上等待所有处理完成.在您想要拥有的常见情况下,这可能会令人愤怒:
当然,当你执行上面的1-6时,所有发生的事情是drawRect 仅在步骤6之后运行一次.
您的目标是在第5点刷新视图.怎么办?
解决原始问题............................................. .
总之,您可以(A)背景大画,并调用前景进行UI更新或(B)可争议地有四种"即时"方法建议不使用后台进程.为了起作用的结果,运行演示程序.它有所有五种方法的#defines.
Tom Swift介绍的真正令人震惊的替代解决方案..................
汤姆斯威夫特解释了非常简单地操纵运行循环的惊人想法.以下是触发运行循环的方法:
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate date]];
这是一个真正令人惊叹的工程.当然,在操作运行循环时应该非常小心,并且许多人指出这种方法严格适用于专家.
引起的奇怪问题............................................. .
尽管许多方法都有效,但实际上并没有"工作",因为在演示中你会看到一个奇怪的渐进式减速神器.
滚动到我在下面粘贴的"答案",显示控制台输出 - 您可以看到它逐渐减慢的速度.
这是新的SO问题:
运行循环/ drawRect中的神秘"渐进式减速"问题
这是演示应用程序的V2 ...
http://www.fileswap.com/dl/p8lU3gAi/stepwiseDrawingV2.zip.html
你会看到它测试所有五种方法,
#ifdef TOMSWIFTMETHOD
[self setNeedsDisplay];
[[NSRunLoop currentRunLoop]
runMode:NSDefaultRunLoopMode beforeDate:[NSDate date]];
#endif
#ifdef HOTPAW
[self setNeedsDisplay];
[CATransaction flush];
#endif
#ifdef LLOYDMETHOD
[CATransaction begin];
[self setNeedsDisplay];
[CATransaction commit];
#endif
#ifdef DDLONG
[self setNeedsDisplay];
[[self layer] displayIfNeeded];
#endif …Run Code Online (Sandbox Code Playgroud) 在我的代码中,我希望"动画"绘制一条线的延迟,所以在向视图添加新行之后,我调用setNeedsDisplay - 它工作正常一次.
在drawRect方法中,我绘制线并调用线的方法来增加line-lengthl.现在我想再次调用setNeedsDisplay来重绘该行 - 所以它得到了一个"成长"的动画.
但它只调用setNeedsDisplay一次并且再也不会调用,除非我添加另一行.我也尝试在这个类中调用一个方法,它调用setNeedsDisplay,以确保你不能在drawRect中调用它.
- (void)drawRect:(CGRect)rect {
for(GameLine *line in _lines) {
if(line.done) {
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(c, 5.0f);
CGContextSetStrokeColor(c, lineColor);
CGContextBeginPath(c);
CGContextMoveToPoint(c, line.startPos.x, line.startPos.y);
CGContextAddLineToPoint(c, line.endPos.x, line.endPos.y);
CGContextStrokePath(c);
}else {
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(c, 5.0f);
CGContextSetStrokeColor(c, delayColor);
CGContextBeginPath(c);
CGContextMoveToPoint(c, line.delayStartPos.x, line.delayStartPos.y);
CGContextAddLineToPoint(c, line.delayEndPos.x, line.delayEndPos.y);
CGContextStrokePath(c);
[line incrementDelayLine];
[self setNeedsDisplay];
}
}
}
Run Code Online (Sandbox Code Playgroud)
_lines是一个带有GameLine对象(非原子,保留)属性的NSMutableArray.