8
votes

I am using Xcode 4.5 and iOS 6.

I am building a universal application that is using storyboards. I have one view controller that has a button in the navigation bar. When the button is tapped, I am using a segue to present another view controller as a modal. The modal view controller has a Cancel and a Save button in its navigation bar. In the storyboard, the modal button items are linked to actions on the new Exit action which is supposed to unwind to the parent view controller, dismiss the modal, and call an action handler.

This works fine on the iPhone, but I am seeing problems on the iPad. On the iPad, when the modal is presented in full screen, everything works. When I change the mode to Page Sheet or Form Sheet (which is the desired behavior in my case), the action handler gets called, but the modal view controller is not being dismissed automatically.

Has anyone else seen this behavior? Is there something that you have done to fix it?

Thank you.

4

4 Answers

6
votes

Thanks for asking about this, since I've just encountered the same issue. I assume that it's a bug, but I have not yet filed it with Apple. In the meantime, the easy workaround is to call dismissViewController:animated: in your unwind: implementation (that is, in the action method connected to the unwind segue through the Exit icon), thus dimissing the modal view yourself.

My only worry about this solution is that if this is a bug and Apple eventually fixes it, will their fix break any code using this workaround? Only time will tell...

Later Edit: I have discovered a much nicer workaround. Subclass the parent (container) class of the class you want to unwind to, and implement unwind there instead. For example, in my app, the situation looks like this:

UISplitViewController
    UINavigationController
        MasterViewController
    UINavigationController
        DetailViewController ----> modal segue ----> ThirdViewController

The exit / unwind segue from ThirdViewController back to DetailViewController demonstrates the bug - the unwind: implementation is called, but the form view is not dismissed. But if I subclass UISplitViewController and implement unwind: there, it works fine. (The unwind: implementation can be empty; the point is that the form view is dismissed automatically.) So evidently this is an issue having to do with container view controllers, and you can solve it by letting the container handle it.

See my example project, uploaded to https://github.com/mattneub/Programming-iOS-Book-Examples/tree/master/ch19p561containerViewControllerStoryboard3Bug

4
votes

Cool if the modal view controller were dismissed automatically, but in Apple's example here, they use a modal transition for the segue but then explicitly call dismissViewControllerAnimated:completion: in the unwind (Exit) action to dismiss it.

2
votes

I had the same issue, so what I did was :

- (IBAction)closeSalesJournal:(UIStoryboardSegue *)segue
{
    // Unwind Segue
    NSLog(@"Closed Sales journal VC");

    // For iPad, need to dismiss the view controller manually
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
        [self dismissViewControllerAnimated:YES completion:nil];
    }
}

That way, I'm sure to leave the standard way for iPhone and force dismissal with iPad.

0
votes

I had a similar problem to this. My modal segue would not unwind. After far too much time wasted, I figured out the problem. It was my fault.

I had a poorly written - (BOOL)canPerformUnwindSegueAction:(SEL)action fromViewController:(UIViewController *)fromViewController withSender:(id)sender in the destination controller. It wasn't expecting the new segue that I had just written, so it was returning NO. In essence, my new segue was being told not to unwind by some other code.