2

在我的代码中,我想“动画”绘制一条线的延迟,因此在向视图添加新线后,我调用 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。

4

2 回答 2

5

这是预期的。

当您调用 setNeedsDisplay 时,您将视图标记为需要重绘。好的。系统得到它。
它将在您的应用程序的主循环下次运行时完成

如果您现在真的想刷新视图,请调用:

[[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate: [NSDate date]];

之后setNeedsDisplay

事实上,苹果文档指出(强调我的):

当您的视图的实际内容发生变化时,您有责任通知系统您的视图需要重绘。为此,您可以调用视图的setNeedsDisplay或 setNeedsDisplayInRect: 方法。这些方法让系统知道它应该在下一个绘图周期更新视图。因为它要等到下一个绘图周期才更新视图,所以可以在多个视图上调用这些方法同时更新它们。

另外,请参阅这些 SO 问题:

于 2013-04-04T20:27:25.427 回答
2

如果您需要动画 - 启动计时器,一旦它被触发 - 调整您想要的任何行参数并调用setNeedsDisplay

于 2013-04-04T20:31:54.630 回答