Unwind Segue not working in iOS 8

IosObjective CIos8

Ios Problem Overview


I have an app, that works fine under iOS 7, but when built for iOS 8 the unwind segues are not working.

I created a new project and added a modal (navigationcontroller with tableviewcontroller)and tried to use an unwind modal. Unfortunately it doesn't work either. The methods that are being unwind to, are in the desination view controller. The unwind segue is created through the storyboard (a Navigationbar button in the tableviewcontroller) When I tap the button, nothing happens. There is no log output and the modal does not disappear. It also only seems to affect modal segues. push/popover are unwound normally.

Has anyone had a similar problem and has an Idea how I could solve it?

Ios Solutions


Solution 1 - Ios

>Apple has FIXED this bug in iOS 8.1

>Temporary solutions for iOS 8.0

>>The unwind segue will not work only in next situation: >>>View structure: UITabBarController -> UINagivationController -> UIViewController1 -> UIViewController2 >>> Normally (in iOS 7, 8.1), When unwind from UIViewController2 to UIViewController1, it will call viewControllerForUnwindSegueAction in UIViewController1. >>> However in iOS 8.0 and 8.0.x, it will call viewControllerForUnwindSegueAction in UITabBarController instead of UIViewController1, that is why unwind segue no longer working. >> Solution: override viewControllerForUnwindSegueAction in UITabBarController by create a custom UITabBarController and use the custom one.

For Swift

CustomTabBarController.swift

import UIKit

class CustomTabBarController: UITabBarController {

    override func viewControllerForUnwindSegueAction(action: Selector, fromViewController: UIViewController, withSender sender: AnyObject?) -> UIViewController? {
        var resultVC = self.selectedViewController?.viewControllerForUnwindSegueAction(action, fromViewController: fromViewController, withSender: sender)
        return resultVC
    }

}

For old school Objective-C

CustomTabBarController.h

#import <UIKit/UIKit.h>

@interface CustomTabBarController : UITabBarController

@end

CustomTabBarController.m

#import "CustomTabBarController.h"

@interface CustomTabBarController ()

@end

@implementation CustomTabBarController

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

@end

>==============================================================================

>DO NOT USE ANY SOLUTIONS BELOW THIS POINT (they are out of date and just for reference)

Latest update on Sep 23

My new solution is pushing to a view that embedded in a navigation controller, and config that navigation controller to hide bottom bar on push(a tick box in IB). Then you will have a view looks like a modal view, the only different is the animate of pushing and popping. You can custom if you want

Updated: The solution below actually present the modal view under the tab bar, which will cause further view layout problems.

Change the segue type to Present As Popover will work only on iOS8 for iPhones, on iOS7 your app will crash.

Same here, to fix this, I set segue's presentation to current context(my app is for iphone only).

Default and full screen will not work.

enter image description here

Solution 2 - Ios

[UPDATE: Bug fixed on iOS 8.1 beta but you'll need it for 8.0 and 8.0.2 support]

The only way I could make my unwind segue work was by mixing Aditya's and viirus' answers.

My setup going in: [View Controller 1] > custom modal segue > [Navigation Controller] > root > [View Controller 2]

Unwind: [View Controller 2] > custom unwind segue > [View Controller 1]

Fix: Subclass the [Navigation Controller], add a property called sourceViewController and pass "self" to that property when prepare for segue is called when going from [View Controller 1] to [Navigation Controller]

In the [Navigation Controller] subclass .m override/add this two methods:

- (UIViewController *)viewControllerForUnwindSegueAction:(SEL)action fromViewController:(UIViewController *)fromViewController withSender:(id)sender
{

    if ([self.sourceViewController canPerformUnwindSegueAction:action fromViewController:fromViewController withSender:sender]) {
	return self.sourceViewController;
    }
    return [super viewControllerForUnwindSegueAction:action fromViewController:fromViewController withSender:sender];   
}

Then I override this in that [Navigation Controller] subclass only because I have a custom unwind segue:

- (UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(NSString *)identifier {
   return [fromViewController segueForUnwindingToViewController:toViewController
										  fromViewController:fromViewController
												  identifier:identifier];
}

Solution 3 - Ios

This is a problem with iOS 8.0, 8.0.1, and 8.0.2. It was resolved in 8.1; unwind segues are calling the appropriate method now.

Note that on iOS 8, modally presented view controllers may not be automatically dismissed when performing an unwind segue, unlike iOS 7. To ensure it's always dismissed, you may detect if it's being dismissed and if not then manually dismiss it. These inconsistencies are resolved in iOS 9.0.

With iOS 8.4 running on iPhone, all of the modally presented segues with all presentation styles do dismiss upon unwind, except Over Full Screen and Over Current Context. That's also the case for iPad, with the addition of Form Sheet and Page Sheet also not auto-dismissing. With iOS 9, all presentation styles auto dismiss on both iPhone and iPad.

Solution 4 - Ios

Yep it kinda happen to me too, I think for your case you have to subclass the UINavigationController and override the following:

    - (UIViewController *)viewControllerForUnwindSegueAction:(SEL)action fromViewController:(UIViewController *)fromViewController withSender:(id)sender
    {

        for(UIViewController *vc in self.viewControllers){
            // Always use -canPerformUnwindSegueAction:fromViewController:withSender:
            // to determine if a view controller wants to handle an unwind action.
            if ([vc canPerformUnwindSegueAction:action fromViewController:fromViewController withSender:sender])
                return vc;
                }


        return [super viewControllerForUnwindSegueAction:action fromViewController:fromViewController withSender:sender];
    }

Solution 5 - Ios

Same problem here. Unwind method is not called. Only happens when

  • using modal segue
  • Presentation is anything but "current context"
  • NavigationController is not extended (using default from storyboard)

Also happens in IOS8 GM Seed, therefore I think we need to find a workaround. Sounds like a bug to me...

Extending UINavigationController and implementing viewControllerForUnwindSegueAction didn't help, as it is not fired. The only thing which gets fired is canPerformUnwindSegueAction() within the extended UINavigationController. Strange.

Solution 6 - Ios

Woah there! I'm still getting user reports of getting stuck on a modal view in iOS 8.1.1 (on an iPad 3).

I'm jettisoning all this unwind from a modal view stuff. Just a good old-fashioned...

[self dismissViewControllerAnimated:NO completion:nil];

...works fine on all those various iOS 8.x.x versions.

Solution 7 - Ios

It seems that both iOS 7.1 and iOS 8.1/8.2 create unwind segue from navigation controller however unwind segue is registered on a child controller inside of navigation controller.

So manually creating an unwind segue from the controller where it's registered in storyboard solves the problem.

@implementation RootNavigationController

- (UIStoryboardSegue*)segueForUnwindingToViewController:(UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(NSString *)identifier {
    return [toViewController segueForUnwindingToViewController:toViewController fromViewController:fromViewController identifier:identifier];
}

@end

Solution 8 - Ios

I encountered the same problem when unwinding to a source view controller from a destination view controller. The destination was presented through a "show" segue from the source. I was using iPhone simulator that shows iPhone 6, iOS8.3. XCode 6.3.2

The solution of subclassing NavigationViewController worked for me. Here is the swift code which is essentially swift translation of Raul's answer. I am puzzled that if Apple has fixed it in iOS8.1 per Raul, how am I getting hit by it in 8.3.

var sourceViewController: UIViewController?
override func viewControllerForUnwindSegueAction(action: Selector, fromViewController: UIViewController, withSender sender: AnyObject?) -> UIViewController? {
        if(self.sourceViewController! .canPerformUnwindSegueAction(action, fromViewController: fromViewController, withSender: sender!)){
            return self.sourceViewController
        }
        return super.viewControllerForUnwindSegueAction(action, fromViewController: fromViewController, withSender: sender)
    }

Solution 9 - Ios

I just ran into this problem, and after some digging discovered that with modal segues (at least ones with the default and fullscreen presentation modes), you can't rely on the normal unwind mechanism, but rather you have to call the presented UIViewController's dismissViewControllerAnimated method.

Solution 10 - Ios

Steps to be followed:

  1. Link the unwind segue to the button in Storyboard.

  2. Create IBAction for the button and add the below code in it:

     [self dismissViewControllerAnimated:NO completion:nil];
    

This should work for all versions.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionviirusView Question on Stackoverflow
Solution 1 - IosStewart HouView Answer on Stackoverflow
Solution 2 - IosRaul ReaView Answer on Stackoverflow
Solution 3 - IosJordan HView Answer on Stackoverflow
Solution 4 - IosAditya WirayudhaView Answer on Stackoverflow
Solution 5 - IosBertlView Answer on Stackoverflow
Solution 6 - IosPaul BradyView Answer on Stackoverflow
Solution 7 - IosRob ZombieView Answer on Stackoverflow
Solution 8 - IosJitendra KulkarniView Answer on Stackoverflow
Solution 9 - Iosuser3483058View Answer on Stackoverflow
Solution 10 - IosSai AppsView Answer on Stackoverflow