In Grand Central Dispatch I want to start a spinner – UIActivityIndicatorView – spinning prior to beginning long running task:
dispatch_async(cloudQueue, ^{
dispatch_async(dispatch_get_main_queue(),
^{
[self spinnerSpin:YES];
});
[self performLongRunningTask];
dispatch_async(dispatch_get_main_queue(),
^{
[self spinnerSpin:NO];
});
});
Here is the spinnerSpin method:
- (void)spinnerSpin:(BOOL)spin {
ALog(@"spinner %@", (YES == spin) ? @"spin" : @"stop");
if (spin == [self.spinner isAnimating]) return;
if (YES == spin) {
self.hidden = NO;
[self.spinner startAnimating];
} else {
[self.spinner stopAnimating];
self.hidden = YES;
}
}
One thing I have never seen discussed is the difference – if any – between [myView setNeedsDisplay] and [myActivityIndicatorView startAnimating]. Do they behave the same?
Thanks,
Doug
The
[UIView setNeedsDisplay]method has nothing to do with aUIActivityIndicatorView‘s animation state.setNeedsDisplaysimply informs the system that this view’s state has changed in a way that invalidates its currently drawn representation. In other words, it asks the system to invoke that view’sdrawRectmethod on the next drawing cycle.You very rarely need to invoke
setNeedsDisplayfrom outside of a view, from code that is consuming the view. This method is meant to be invoked by the view’s internal logic code, whenever something changes in its internal state that requires a redraw of the view.The
[UIActivityIndicatorView startAnimating]method is specific to theUIActivityIndicatorViewclass and simply asks the indicator to start animating (e.g. spinning). This method is instant, without requiring you to call any other method.On a side note, you could simplify your code by simply calling
startAnimatingorstopAnimatingwithout manually showing/hiding it. TheUIActivityIndicatorViewclass has ahidesWhenStoppedboolean property that defaults toYES, which means that the spinner will show itself as soon as it starts animating, and hide itself when it stops animating.So your
spinnerSpin:method could be refactored like this (as long as you haven’t set thehidesWhenStoppedproperty toNO):