I have a complex Quartz routine in drawRect for a custom UIView subclass. It can take a few seconds to draw. What I’d like is to show a UIActivityIndicator while it is drawing. But then the indicator must stop spinning (and get hidden) after the drawing is complete.
I tried to start the animation of the indicator and then use performSelector for a custom method that simply calls setNeedsDisplay – my thinking is that performSelector will wait until the next run loop, right? In which case, my indicator has time to start on the main thread. This seems to be working, but as soon as I add the code to the end of drawRect to stop the animation, the indicator doesn’t show up at all, as if this animation is ending before it’s had a chance to begin.
Any suggestions?
I call the drawing like this:
[self.spinner startAnimating];
[self performSelectorOnMainThread:@selector(redraw) withObject:nil waitUntilDone:YES];//tried both YES and NO here
-(void)redraw{
[self.customView setNeedsDisplay];
}
The drawRect: simply has this at the end:
- (void)drawRect:(CGRect)rect{
//bunch of drawing
[self.nav stopSpinner]; // reference to a controller class
}
In self.nav object is this:
-(void)stopSpinner{
self.spinner.hidden=YES;
[self.spinner stopAnimating];
}
And the spinner object is initially created like this:
self.spinner=[[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]autorelease];
self.spinner.hidden=YES;
[self.viewController.view addSubview:self.spinner];
Perform your drawing on a background thread. Not only will this allow you to throw up an activity indicator and have it animate as desired, but the drawing itself with be much much faster. In my tests, I’ve seen a speed increase of 10X in complex Quartz drawing on a background thread.
And it’s not hard. In fact, it might be so fast you won’t need the activity indicator.
Here’s the code, and you can simply use a regular
UIImageViewand then assign itsimageproperty to the rendered output from the other thread: