-segueForUnwindingToViewController: fromViewController: identifier: not being called

I have created a custom segue that presents a view controller inside a container that is very similar with Apple’s own modal view controllers (I’ve implemented it as a UIViewController subclass).

I’m now trying to create a custom unwind segue but there’s no way I can get the method -segueForUnwindingToViewController: fromViewController: identifier: to be called.

  • Swift link Image from Parse array using segues to secondViewController
  • iPad: file was built for armv7 which is not the architecture being linked (arm64)
  • “Unknown class in interface builder file” when using class which inherits from a generic class in a Storyboard
  • iOS: Determine if device language is Right to Left (RTL)
  • Loading web page in UIWebView in Xcode 4.2 — how to connect IBOutlets properly and ensure the web page loads?
  • How to play an audio if we pass NSData?
  • I’ve also implemented -viewControllerForUnwindSegueAction: fromViewController: withSender: on my container so I can point to the correct view controller (the one that presented this modal) but then the method that should be asked for my custom unwind segue doesn’t get called anywhere.

    Right now, the only way for me to dismiss this modal is to do it on the -returned: method.

    Did anyone could successfully do this with a custom unwind segue?


    EDIT:
    A little bit more code and context

    My unwind view controller is configured in the storyboard, not programatically.

    I have these pieces of code related to the unwind segues in my controllers:

    PresenterViewController.m

    I’m using a custom method to dismiss my custom modals here (-dismissModalViewControllerWithCompletionBlock:).

    - (UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController *)toViewController
                                          fromViewController:(UIViewController *)fromViewController
                                                  identifier:(NSString *)identifier {
        return [[MyModalUnwindSegue alloc] initWithIdentifier:identifier
                                                       source:fromViewController
                                                  destination:toViewController];
    }
    
    -(IBAction)returned:(UIStoryboardSegue *)segue {
        if ([segue.identifier isEqualToString:@"InfoUnwindSegue"]) {
            [self dismissModalViewControllerWithCompletionBlock:^{}];
        }
    }
    

    MyModalViewController.m

    Here I only use -viewControllerForUnwindSegueAction: fromViewController: withSender: to point to the view controller that I should be unwind to.

    - (UIViewController *)viewControllerForUnwindSegueAction:(SEL)action 
                                          fromViewController:(UIViewController *)fromViewController 
                                                  withSender:(id)sender {
        return self.myPresentingViewController;
    }
    

    The behavior I was expecting was that MyModalViewController was called to point to the view controller that should handle the unwinding and then this view controller had his -segueForUnwindingToViewController: fromViewController: identifier: method called before -returned: gets called.

    Right now -segueForUnwindingToViewController: fromViewController: identifier: never gets called.

    I must also say that I already tried different configurations. Everywhere I put my method to return the unwind segue it never gets called. I’ve read that I can subclass a navigation controller and then it gets called but I don’t know how it would fit in my solution.


    EDIT 2: Additional info

    I’ve checked that MyModalViewController has his -segueForUnwindingToViewController: fromViewController: identifier: method called when I want to dismiss a regular modal view controller presented by it. This may be because he’s the top most UIViewController in the hierarchy.

    After checking this I’ve subclassed UINavigationController and used this subclass instead to contain my PresenterViewController. I was quite surprised to notice that his -segueForUnwindingToViewController: fromViewController: identifier: method is called as well.

    I believe that only view controllers that serve as containers have this method called. That’s something that makes little sense for me as they are not the only ones presenting other view controllers, their children are also doing so.

    It’s not OK for me to create logic in this subclass to choose which segue class to use as this class has no knowledge of what their children did.

    Apple forums are down for the moment so no way to get their support right now. If anyone has any more info on how this works please help! I guess the lack of documentation for this is a good indicator of how unstable this still is.

    4 Solutions Collect From Internet About “-segueForUnwindingToViewController: fromViewController: identifier: not being called”

    To add to the answer from @Jeremy, I got unwinding from a modal UIViewController to a UIViewController contained within a UINavigationController to work properly (I.e how I expected it to) using the following within my UINavigationController subclass.

    // Pass to the top-most UIViewController on the stack.
    - (UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController *)
                 toViewController fromViewController:(UIViewController *)
                 fromViewController identifier:(NSString *)identifier {
       UIViewController *controller = self.topViewController;
       return [controller segueForUnwindingToViewController:toViewController
                                      fromViewController:fromViewController
                                              identifier:identifier];
    }
    

    .. and then implementing the segueForUnwindingToViewController as usual in the actual ViewController inside the UINavigationController.

    This method should be declared on the parent controller. So if you’re using a Navigation Controller with a custom segue, subclass UINavigationController and define this method on it. If you would rather define it on one of the UINavigationController’s child views, you can override canPerformUnwindSegueAction:fromViewController:withSender on the UINavigationController to have it search the children for a handler.

    If you’re using an embedded view (container view), then define it on the parent view controller.

    See the last 10 minutes of WWDC 2012 Session 407 – Adopting Storyboards in Your App to understand why this works!

    If you’re using a UINavigationController and your segue is calling pushViewController then in order to use a custom unwind segue you’ll need to subclass UINavigationController and override - (UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(NSString *)identifier.

    Say I have a custom unwind segue called CloseDoorSegue. My UINavigationController subclass implementation might look something like:

    - (UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(NSString *)identifier {
    
    UIStoryboardSegue* theSegue;
    
    if ([identifier isEqualToString:@"CloseDoor"]) {
        theSegue = [CloseBookSegue segueWithIdentifier:identifier source:fromViewController destination:toViewController performHandler:^(void){}];
    } else {
        theSegue = [super segueForUnwindingToViewController:toViewController fromViewController:fromViewController identifier:identifier];
    }
    
    return theSegue;
    

    }

    Set your UINavigationController subclass as the navigation controller class in the storyboard. You should be good to go provided you have setup the Exit event correctly with “CloseDoor” as the identifier. Also be sure to call ‘popViewControllerAnimated’ in your unwind segue instead of dismiss to keep in line with UINavigationControllers push/pop mechanism.

    iOS development Library
    There is a discussion on iOS development Library along with this method.
    – segueForUnwindingToViewController:fromViewController:identifier:
    Make sure your MyModalViewController is the container role rather than a subcontroller of a container. If there is something like [anotherVC addChildViewController:myModalViewController];,you should put the segueForUnwindingToViewController method in some kind of “AnotherVC.m” file.

    Discussion
    If you implement a custom container view controller that
    also uses segue unwinding, you must override this method. Your method
    implementation should instantiate and return a custom segue object
    that performs whatever animation and other steps that are necessary to
    unwind the view controllers.