So when I click on a callout accessory in my mapView, nothing happens for several seconds because it is making a url request and parsing it, so I wanted to show the activity indicator so the user doesn’t think it’s frozen. Here’s the code:
- (void)mapView:(MKMapView *)mv annotationView:(MKAnnotationView *)pin calloutAccessoryControlTapped:(UIControl *)control {
// start activity indicator
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSLog(@"tapped");
ArtPiece *artPiece = (ArtPiece *)pin.annotation;
//when annotation is tapped switches page to the art description page
artDescription *artD = [[artDescription alloc] initWithNibName:@"artDescription" bundle:nil];
artD.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
artD.startingLocation = mapView.userLocation.location.coordinate;
artD.selectedArtPiece = artPiece;
NSLog(@"0");
[self presentModalViewController:artD animated:YES];
NSLog(@"1");
[artD loadArt:artPiece];
NSLog(@"2");
// stop activity indicator
//[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
[artD release];
}
Strangely (to me anyway, maybe I’m missing something obvious as I’m pretty inexperienced), the activity indicator does not show until after the method is done, and the modal view starts animating into view. I put the NSLogs in to see what was taking time. I had about a 2 second pause between “0” and “1” and another couple seconds between “1” and “2”. Then the indicator finally showed, so I am sure it is waiting until the end of the method for some reason. Any ideas why?
The change to the UI, displaying the activity indicator, does not take effect until control has returned to the application’s main run loop. This does not occur until after your method has ended and the stack has unwound. You need to show the activity indicator, then dump the activity you are waiting for onto a background thread:
(Note that Apple recommends that you move away from using threads explicitly;
performSelectorInBackground:withObject:is the simplest method to get some code run off the main thread. More complex options are available for other situations. See the Concurrency Programming Guide.)The important gotcha is that UI updates still need to be handled on the main thread, so in that method, when the work is done, you need to call back to stop the activity indicator:
In your callback method, you hide the activity indicator again and do any other post-processing that’s necessary.