Search code examples
objective-cuipopovercontrollermodalviewcontroller

Dismiss only 1 of 2 modally presented view controllers


A UINavigation controller is used as a modal popover and then presented:

XYNavigationController *popoverNavigationController = [self.storyboard instantiateViewControllerWithIdentifier:@"XYNavigationController"];
popoverNavigationController.modalPresentationStyle = UIModalPresentationPopover;
XYCartViewController *cartVC = (XYCartViewController *)popoverNavigationController.topViewController;
[self presentViewController:popoverNavigationController animated:YES completion:nil];

When a button is tapped, another controller, XYEditViewController, is presented modally on top of the modal popoverNavigationController. XYEditViewController's cancel button calls an unwind segue:

- (IBAction)unwindFromEdit:(UIStoryboardSegue *)segue {
    //a. [segue.sourceViewController dismissViewControllerAnimated:YES completion:nil];
    //b. [self.navigationController.topViewController dismissViewControllerAnimated:YES completion:nil];
    //c. [(XYCartViewController*)(segue.destinationViewController) dismissViewControllerAnimated:YES completion:nil];
    //d.
    [(XYNavigationController*)(((XYEditViewController*)(segue.sourceViewController)).presentingViewController) dismissViewControllerAnimated:YES completion:nil];

}

Expecting Cancel button to dismiss just the top modal controller and have tried all a,b,c,d above and they all dismiss both the top and popover controller. Any idea how to dismiss only the top controller in this situation?


Solution

  • Dismissal of a presented controller inside a popover is a huge problem (i.e. bug), and is not helped by the fact that this behavior has changed many times over the course of iOS history. Basically you won't be able to use an unwind segue for this, I believe. Just have Cancel button do an action in the presented view controller that calls [self dismissViewControllerAnimated:].

    (You will also have to grapple with what happens the user taps outside the popover; by default this may also dismiss the whole pair, which I think is wrong behavior.)