Ok. So I'm working on a game in sprite kit using objective C. I have a method that I call that uses the viewcontroller the skscene is running from to call a uialertcontroller at game over. Upon pressing the ok button in the alert view, I modal back to the main menu view controller. This works fine. However when I go to play the game again, switching back to the gameviewcontroller and get another game over, the uialertview fails to trigger. I get an error message saying:
Warning: Attempt to present <UIAlertController: 0x14205d600> on <GameViewController: 0x141e176f0> whose view is not in the window hierarchy!
Here is the code where I call the UIAlertController:
UIAlertController * gameOverAlert = [UIAlertController alertControllerWithTitle: @"Game Over!" message: textscore preferredStyle: UIAlertControllerStyleAlert];
//add the button that will take us back to the main menu
UIAlertAction *okButton = [UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){
[UIApplication.sharedApplication.keyWindow.rootViewController.presentedViewController performSegueWithIdentifier:@"backToTheMenuNotFuture" sender:self];
}];
[gameOverAlert addAction: okButton];
[UIApplication.sharedApplication.keyWindow.rootViewController.presentedViewController presentViewController: gameOverAlert animated:true completion: nil];
Here is the code for when I modal to the gameviewcontroller:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:@"gotoPlay"]){
gameController = (GameViewController *)segue.destinationViewController;
gameController.playingMusic = musicHave;
}
}
As I said, this work fine the first game, but when you go to play again and lose a second time, that's when the error happens.
Solved:
(isDismissed is an int value starting off as 0)
//add the button that will take us back to the main menu
UIAlertAction *okButton = [UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){
isDismissed = 1;
[UIApplication.sharedApplication.keyWindow.rootViewController.presentedViewController performSegueWithIdentifier:@"backToTheMenuNotFuture" sender:self];
}];
[gameOverAlert addAction: okButton];
[UIApplication.sharedApplication.keyWindow.rootViewController.presentedViewController presentViewController: gameOverAlert animated:true completion: nil];
if(isDismissed == 1){
[UIApplication.sharedApplication.keyWindow.rootViewController.presentedViewController dismissViewControllerAnimated:NO completion: nil];
[UIApplication.sharedApplication.keyWindow.rootViewController.presentedViewController presentViewController: gameOverAlert animated:true completion: nil];
[UIApplication.sharedApplication.keyWindow.rootViewController.presentedViewController performSegueWithIdentifier:@"backToTheMenuNotFuture" sender:self];
}
}
So the issue here as in the comments is that there were multiple gameviewcontroller instances running at once. The code above dismisses the 'current' gameviewcontroller and then attempts to run what I want to the original one. It works, however I am unsure of whether or not the game is then deallocating the old gameviewcontroller or creating yet more duplicates every time it runs. In the end I see it as this. If it is deallocating like it should then its fine. If its not, then the game which I'd say consumes about 8MB of RAM would eventually cause the iPhone to lag. If this does happen then you have obviously been playing it for so long that you should really take a break from it anyway. Its not a bug, its a feature!