Question

In my code I want to "animate" a delay of drawing a line, so after adding a new line to the view, I call setNeedsDisplay - which works fine once.

Inside the drawRect method I draw the line and call a method of the line to increment the line-lengthl. Now I want to call setNeedsDisplay again to redraw the line - so it get's an animation of "growing"..

But it only calls setNeedsDisplay once & never again, except I add another line. I also tried to call a method in this class, which calls setNeedsDisplay, to make sure you can't call it inside of 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 is a NSMutableArray with the GameLine objects (nonatomic, retain) property.

Was it helpful?

Solution 2

If you need an animation - start a timer, once it's fired - adjust whatever line parameter you want and call setNeedsDisplay

OTHER TIPS

It is expected.

When you call setNeedsDisplay, you mark the view as needing to be redrawn. OK. The system gets it.
And it will be done the next time the main loop of your app runs.

If you really want to refresh the view now call:

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

just after setNeedsDisplay.

Indeed, apple documentation states (emphasis mine):

When the actual content of your view changes, it is your responsibility to notify the system that your view needs to be redrawn. You do this by calling your view’s setNeedsDisplay or setNeedsDisplayInRect: method of the view. These methods let the system know that it should update the view during the next drawing cycle. Because it waits until the next drawing cycle to update the view, you can call these methods on multiple views to update them at the same time.

Also, see these SO questions:

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top