Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

-segueForUnwindingToViewController: fromViewController: identifier: not being called

Tags:

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.

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.

like image 372
Fábio Oliveira Avatar asked Jul 18 '13 10:07

Fábio Oliveira


2 Answers

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.

like image 89
Ben Clayton Avatar answered Oct 11 '22 15:10

Ben Clayton


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!

like image 31
Jeremy Massel Avatar answered Oct 11 '22 17:10

Jeremy Massel