Unwind Segue 在 iOS 8 中不起作用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25654941/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Unwind Segue not working in iOS 8
提问by viirus
I have an app, that works fine under iOS 7, but when built for iOS 8 the unwind segues are not working.
我有一个应用程序,它在 iOS 7 下运行良好,但是当为 iOS 8 构建时,unwind segues 不起作用。
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.
我创建了一个新项目并添加了一个模式(带有 tableviewcontroller 的导航控制器)并尝试使用展开模式。不幸的是它也不起作用。正在展开的方法位于目标视图控制器中。展开转场是通过情节提要(tableviewcontroller 中的导航栏按钮)创建的,当我点击按钮时,没有任何反应。没有日志输出,模态不会消失。它似乎也只影响模态转场。push/popover 正常展开。
Has anyone had a similar problem and has an Idea how I could solve it?
有没有人遇到过类似的问题,并且有我如何解决的想法?
采纳答案by Stewart Hou
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 UIViewController2to UIViewController1, it will call viewControllerForUnwindSegueActionin UIViewController1.
However in iOS 8.0 and 8.0.x, it will call viewControllerForUnwindSegueActionin UITabBarControllerinstead of UIViewController1, that is why unwind segue no longer working.
Solution:override viewControllerForUnwindSegueActionin UITabBarControllerby create a custom UITabBarControllerand use the custom one.
Apple 已在 iOS 8.1 中修复此错误
iOS 8.0 临时解决方案
只有在下一种情况下,unwind segue 才会起作用:
视图结构:UITabBarController-> UINagivationController-> UIViewController1-> UIViewController2
通常(在 iOS 7、8.1中),当从UIViewController2 展开到UIViewController1 时,它会调用UIViewController1 中的viewControllerForUnwindSegueAction。
但是在 iOS 8.0 和 8.0.x 中,它会在UITabBarController 中调用viewControllerForUnwindSegueAction而不是UIViewController1,这就是为什么 unwind segue 不再工作的原因。
解决方案:覆盖viewControllerForUnwindSegueAction中的UITabBarController通过创建一个自定义的UITabBarController和使用自定义之一。
For Swift
对于斯威夫特
CustomTabBarController.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
对于老派的Objective-C
CustomTabBarController.h
自定义TabBarController.h
#import <UIKit/UIKit.h>
@interface CustomTabBarController : UITabBarController
@end
CustomTabBarController.m
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
9 月 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
我的新解决方案是推送到嵌入在导航控制器中的视图,并配置该导航控制器以隐藏推送时的底部栏(IB 中的复选框)。然后你会有一个看起来像模态视图的视图,唯一不同的是推和弹出的动画。如果您愿意,您可以自定义
Updated: The solution below actually present the modal viewunder the tab bar, which will cause further view layout problems.
更新:下面的解决方案实际上是在标签栏下呈现模态视图,这将导致进一步的视图布局问题。
Change the segue type to Present As Popoverwill work only on iOS8for iPhones, on iOS7 your app will crash.
将 segue 类型更改为Present As Popover仅适用于iPhone 的iOS8,在 iOS7 上您的应用程序将崩溃。
Same here, to fix this, I set segue's presentation to current context(my app is for iphone only).
同样在这里,为了解决这个问题,我将 segue 的演示文稿设置为当前上下文(我的应用程序仅适用于 iphone)。
Default and full screen will not work.
默认和全屏将不起作用。
回答by Raul Rea
[UPDATE: Bug fixed on iOS 8.1 beta but you'll need it for 8.0 and 8.0.2 support]
[更新:在 iOS 8.1 beta 上修复了错误,但你需要它来支持 8.0 和 8.0.2]
The only way I could make my unwind segue work was by mixing Aditya's and viirus' answers.
我可以让我的放松转场工作的唯一方法是混合 Aditya 和 viirus 的答案。
My setup going in: [View Controller 1] > custom modal segue > [Navigation Controller] > root > [View Controller 2]
我的设置进入:[View Controller 1] > 自定义模式 segue > [Navigation Controller] > root > [View Controller 2]
Unwind: [View Controller 2] > custom unwind segue > [View Controller 1]
展开:[视图控制器 2] > 自定义展开转场 > [视图控制器 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]
修复:子类化 [Navigation Controller],添加一个名为 sourceViewController 的属性,并在从 [View Controller 1] 转到 [Navigation Controller] 时调用 prepare for segue 时将“self”传递给该属性
In the [Navigation Controller] subclass .m override/add this two methods:
在 [Navigation Controller] 子类 .m 中重写/添加这两个方法:
- (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:
然后我在 [Navigation Controller] 子类中覆盖它只是因为我有一个自定义的展开转场:
- (UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(NSString *)identifier {
return [fromViewController segueForUnwindingToViewController:toViewController
fromViewController:fromViewController
identifier:identifier];
}
回答by Jordan H
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.
这是 iOS 8.0、8.0.1 和 8.0.2 的问题。它在 8.1 中得到解决;unwind segues 现在正在调用适当的方法。
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.
请注意,在 iOS 8 上,与 iOS 7 不同,在执行 unwind segue 时,模态呈现的视图控制器可能不会自动关闭。为确保它始终被关闭,您可以检测它是否被关闭,如果没有,则手动关闭它。这些不一致在 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.
在 iPhone 上运行 iOS 8.4 时,除了 Over Full Screen 和 Over Current Context 之外,所有呈现样式的所有模态呈现的 segue 都会在展开时关闭。iPad 的情况也是如此,添加的 Form Sheet 和 Page Sheet 也不会自动关闭。使用 iOS 9,iPhone 和 iPad 上的所有演示样式都会自动关闭。
回答by Aditya Wirayudha
Yep it kinda happen to me too, I think for your case you have to subclass the UINavigationController and override the following:
是的,它也发生在我身上,我认为对于您的情况,您必须继承 UINavigationController 并覆盖以下内容:
- (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];
}
回答by Bertl
Same problem here. Unwind method is not called. Only happens when
同样的问题在这里。不调用 Unwind 方法。只发生在
- using modal segue
- Presentation is anything but "current context"
- NavigationController is not extended (using default from storyboard)
- 使用模态转场
- 演示文稿绝不是“当前上下文”
- NavigationController 未扩展(使用故事板中的默认值)
Also happens in IOS8 GM Seed, therefore I think we need to find a workaround. Sounds like a bug to me...
也发生在 IOS8 GM Seed 中,因此我认为我们需要找到一种解决方法。对我来说听起来像是一个错误......
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.
扩展 UINavigationController 和实现 viewControllerForUnwindSegueAction 没有帮助,因为它没有被触发。唯一被触发的是扩展 UINavigationController 中的 canPerformUnwindSegueAction()。奇怪的。
回答by Paul Brady
Woah there! I'm still getting user reports of getting stuck on a modal view in iOS 8.1.1 (on an iPad 3).
哇哦!我仍然收到用户报告说在 iOS 8.1.1(在 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.
...在所有这些不同的 iOS 8.xx 版本上都可以正常工作。
回答by Ben Sinclair
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.
似乎 iOS 7.1 和 iOS 8.1/8.2 都从导航控制器创建了 unwind segue,但是 unwind segue 是在导航控制器内的子控制器上注册的。
So manually creating an unwind segue from the controller where it's registered in storyboard solves the problem.
因此,从它在故事板中注册的控制器手动创建一个 unwind segue 解决了这个问题。
@implementation RootNavigationController
- (UIStoryboardSegue*)segueForUnwindingToViewController:(UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(NSString *)identifier {
return [toViewController segueForUnwindingToViewController:toViewController fromViewController:fromViewController identifier:identifier];
}
@end
回答by Jitendra Kulkarni
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
从目标视图控制器展开到源视图控制器时,我遇到了同样的问题。目的地是通过来自源的“show”segue 呈现的。我使用的是显示 iPhone 6、iOS8.3 的 iPhone 模拟器。代码 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.
子类化 NavigationViewController 的解决方案对我有用。这是快速代码,它本质上是 Raul 答案的快速翻译。我很困惑,如果 Apple 已经按照 Raul 在 iOS8.1 中修复了它,我怎么会在 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)
}
回答by user3483058
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.
我刚遇到这个问题,经过一些挖掘发现,使用模态转场(至少具有默认和全屏呈现模式的),您不能依赖正常的展开机制,而必须调用呈现的 UIViewController 的dismissViewControllerAnimated方法。
回答by Sai Apps
Steps to be followed:
应遵循的步骤:
- Link the unwind segue to the button in Storyboard.
Create IBAction for the button and add the below code in it:
[self dismissViewControllerAnimated:NO completion:nil];
- 将 unwind segue 链接到 Storyboard 中的按钮。
为按钮创建 IBAction 并在其中添加以下代码:
[self dismissViewControllerAnimated:NO completion:nil];
This should work for all versions.
这应该适用于所有版本。