Eliminating ViewControllerAnimated Rejection: Completion: Generates different results in iOS 7 and iOS 8

I have a UIViewController, which I will call root, which represents (via modal segue) another UIViewController (firstChild), which presents (again via modal segue) a UINavigationController (topChild). In the top child, I do the following:

[root dismissViewControllerAnimated:NO completion:^{
    [root performSegueWithIdentifier:@"ToNewFirstChild" sender:self];
}];

      

In iOS 7, the effect of this is that the topChild stays on screen until the segue for newFirstChild is complete, and then newFirstChild (represented by root) is displayed. I like it.

In iOS 8, the effect is that topChild is immediately removed from the screen, firstChild is briefly displayed and then removed, leaving root to display until the segue completes, and then newFirstChild (represented by root) is displayed. I do not like this.

If I choose to animate dismissViewControllerAnimated:completion:

, the following results are obtained: In iOS 7, topChild is fired with animation, without revealing firstChild (as stated in the documentation), leaving root to display until the segue is complete; and in iOS8 the topChild is immediately removed from the screen, leaving firstChild, which is rejected with animation (unlike the documentation!), again leaving root to be displayed until the segue completes.

Any idea how I can get the effect created in iOS 7 (with or without animation) in iOS 8? What am I missing?

+3


source to share


1 answer


The problem you are having is that you are trying to call a method on the completion block of the dismissViewControllerAnimated:completion

view manager that you are rejecting (and therefore freeing), thus sporadic and unpredictable behavior.

I would recommend using something like NSNotificationCenter

to post a notification when the view manager is dismissed and keep the handler in the parent (root) controller that can receive the notification.

In your root view controller, call this somewhere (maybe prepareForSegue

?):

[[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(topChildWasDismissed:)
                                                 name:@"TopChildDismissed"
                                               object:nil];

      



You will also need a handler method in the root VC:

- (void)topChildWasDismissed {
    [self performSegueWithIdentifier:@"ToNewFirstChild" sender:self];
}

      

Then in your top child:

[self dismissViewControllerAnimated:YES completion:^(void) {
    [[NSNotificationCenter defaultCenter] postNotificationName:@"TopChildDismissed" object:self];
}];

      

0


source







All Articles