I’m transitioning between my game’s main menu and the game itself, and am in need of a loading screen. The current behavior is that I tap the Play button, and there’s no movement and no segue for a few seconds, then the game begins.
Temporarily, I’m just throwing up a UIActivityIndicatorView and manually telling it to startAnimating, then calling the segue to the other scene. The issue is that code from the game view (the end-point of the segue) is being run before the view has physically changed on-screen (i.e. I’m seeing the menu while code from the game is being executed). I don’t quite see how this happens, since the spinner is told to display before the segue is called. Here’s the code:
- (IBAction) startGame: (id) sender
{
[_loadingView setHidden: NO];
[_loadingSpinner startAnimating];
[self performSegueWithIdentifier: @"PlayGame" sender: self];
}
The stuff that’s actually taking the time isn’t called until the segue has completed (i.e. until the game’s main view is shown onscreen in an entirely different ViewController (it’s querying an SQLite database)), so why is the spinner not showing until after that work has been done? Should I be using GCD or similar for this? I’ve done a little experimenting with it but it might be a tad above my level at present. The heavy code is contained in one method, so I’d ideally like to be able to do something like this, literally executing the lines in order.
[spinner startAnimating];
[self callMethodThatTakesAges];
[spinner stopAnimating];
I’ve tried using performSelectorOnMainThread:withObject:waitUntilDone:, but it seems to be getting confused between the two views. The spinner should show on the game view, not the menu view, ideally, so I should tap Play, the transition to the game view should be instant, then the spinner should appear, loading should start, spinner should vanish when done.
Any ideas? Thanks!
EDIT: Here are some methods from my game view controller (makeNewWord is the troublesome method).
- (void) viewDidAppear: (BOOL) animated
{
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle: UIActivityIndicatorViewStyleWhiteLarge];
[spinner setCenter: CGPointMake(240, 55)];
[self.view addSubview: spinner];
[spinner startAnimating];
[self makeNewWord];
[spinner stopAnimating];
[self becomeFirstResponder];
}
- (void) viewDidLoad
{
[super viewDidLoad];
[self canBecomeFirstResponder];
firstLetterMultiplierLetter = [[NSString alloc] init];
userIsEnteringAWord = NO;
[self setUpGestures];
}
Here’s the method called from my main menu view that segues into the game view:
- (IBAction) startGame: (id) sender
{
[self performSegueWithIdentifier: @"PlayGame" sender: self];
}
It’s hard to tell what you have where from your question. I would say you want to do this:
The only thing in your startGame: method should be the performSegue line. You might also need to change where you start the download to where I said, it’s not clear where you’re starting that now.