I have a ViewController that takes time to load its views. When I run Instruments, I see from the home screen, if I tap on the icon that pushes that view controller onto the stack, it's half laying out the views, and half getting the data for the views. I tried adding an activity indicator to display on the home screen over the button when the button is pressed to push the LongRunningViewController onto the stack. So I basically do this:
- (IBAction)puzzleView:(id)sender {
dispatch_async(dispatch_get_main_queue(), ^{
[self.activityIndicator startAnimating];
});
PuzzleViewController *detailViewController = [[[PuzzleViewController alloc] init] autorelease];
[self.navigationController pushViewController:detailViewController animated:YES];
[self.activityIndicator stopAnimating];
}
The home screen lags while pressing the button, and then loads the view. I'm trying to show the activity indicator while the other screen is preparing to be pushed (or at least that's the way I think it works). The activity indicator does not show however. I'm wondering if this can be done? Or do other apps push their ViewController, and then on that screen, they have the activity indicators showing the loading of their different resources?
When you say that it takes time to get the data for the views, I assume you mean that the PuzzleViewController
does something non-trivial somewhere like viewDidLoad
.
So let's say it is in viewDidLoad
. Then you can do this:
-(void)viewDidLoad
{
[self.activityIndicator startAnimating];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
{
//do something expensive
[self doSomethingExpensive];
//dispatch back to the main (UI) thread to stop the activity indicator
dispatch_async(dispatch_get_main_queue(), ^
{
[self.activityIndicator stopAnimating];
});
});
}
This will mean that the expensive operation will be put on a background thread and won't block the loading/showing of the view controller.
This approach is showing the requested view immediately when the user pushes the button, and showing progress on that screen. I think it's more common this way than to show an activity view while loading contents before presenting the view. This also buys you a little bit more time; your long operation can be running in the background during the transition animation!
The reason your activity view isn't showing the way you're doing it is that you're doing it all on the UI thread; using dispatch_async
to the main queue from the main queue won't accomplish anything because your block won't have a chance to run until the run loop completes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With