0
votes

How can I reflect UIView changes of a setNeedsDisplay?

In drawRect triggered by setNeedsDisplay

- (void)drawRect:(CGRect)rect {
   double i = 0;
   for(...)
   //i is incremented
       dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(i * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                drawStuff(element, context);
       });

For example, each draw update would happen after 1s, 2s, 3s, ...

DrawStuff switches back to the main thread with

dispatch_async(dispatch_get_main_queue(), ^(void) { ...

when updating the UI. I have tried both UIBezierPath and Core Graphics and get the same results. I am also using UIGraphicsPushContext and UIGraphicsPopContext to get the correct context.

Using NSLog, I can tell the drawStuff is called in the 1s increments. However, the visible UIView remains unchanged. I can rotate the device screen and this will reposition the UIView and change its size. On rotation the UIView will reflect what it has currently drawn, but then I need to rotate it again to see the updated state after a few seconds.

Back to the question above, is there a call to tell UIView to display its current graphics after setNeedsDisplay? Thanks.

1

1 Answers

1
votes

If you are trying to make sure your view is redrawn once per second, the right way to do this is to set some form of timer elsewhere in your view, and have the timer function call -setNeedsDisplay. This will in turn invalidate your view and cause your -drawRect: to be called, which should do the drawing (ie call your drawStuff)

Conceptually, -drawRect: should only be a dumb method that just knows how to do the actual drawing work based on whatever the current state of the view is. Your normal event logic (or a timer) outside of that should (a) update the state as necessary and (b) mark the view as needing to be redrawn.