setNeedsDisplay 只被调用一次
Posted
技术标签:
【中文标题】setNeedsDisplay 只被调用一次【英文标题】:setNeedsDisplay only gets called once 【发布时间】:2013-04-04 20:22:38 【问题描述】:在我的代码中,我想“动画化”绘制一条线的延迟,因此在向视图添加新线后,我调用 setNeedsDisplay - 一次可以正常工作。
在 drawRect 方法中,我绘制了线条并调用线条的方法来增加线条长度l。现在我想再次调用 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];
_lines 是具有 GameLine 对象(非原子,保留)属性的 NSMutableArray。
【问题讨论】:
【参考方案1】:这是意料之中的。
当您调用 setNeedsDisplay 时,您将视图标记为需要重绘。好的。系统得到它。 它会在你的应用程序的主循环下次运行时完成。
如果您真的想现在刷新视图,请致电:
[[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate: [NSDate date]];
就在setNeedsDisplay
之后。
确实,apple documentation 状态(强调我的):
当您的视图的实际内容发生变化时,它是您的 有责任通知系统您的视图需要 重绘。您可以通过调用视图的 setNeedsDisplay 或 setNeedsDisplayInRect:视图的方法。 这些方法让 系统知道它应该在下一次绘图期间更新视图 周期。因为它会等到下一个绘图周期更新 视图,您可以在多个视图上调用这些方法来更新它们 同一时间。
另外,请参阅这些 SO 问题:
How to force a view to render itself? Is there a way to make drawRect work right NOW?(和你一样担心)【讨论】:
我添加了一个 "NSLog(@"Count: %d", [_lines count]);"到for循环之前的drawRect,它在添加一行之前出现了几次 - 然后又出现了一次,之后就没有了.. @Christian'fuzi'Orgler 一旦你调用了setNeedsDisplay
,系统将不会考虑任何其他调用,直到视图被重绘(即直到你的应用程序主循环运行我>)。这是因为您已经明确表示下次模态循环运行时应该重绘视图。如果您希望每次调用 setNeedsDisplay
时都重新绘制视图,请使用我的答案中提供的代码。
注意:请注意在drawRect:
中调用setNeedsDisplay
会导致循环调用,从而导致性能非常糟糕。【参考方案2】:
如果您需要动画 - 启动计时器,一旦它被触发 - 调整您想要的任何行参数并调用 setNeedsDisplay
【讨论】:
以上是关于setNeedsDisplay 只被调用一次的主要内容,如果未能解决你的问题,请参考以下文章
uiview 子类在第一次调用 setneedsdisplay 时显示为黑色矩形,但在那之后就可以了
didSelectRowAtIndexPath 只被调用一次