Unwind Segue 在 iOS 8 中不起作用

Posted

技术标签:

【中文标题】Unwind Segue 在 iOS 8 中不起作用【英文标题】:Unwind Segue not working in iOS 8 【发布时间】:2014-09-03 23:03:51 【问题描述】:

我有一个应用程序,在 ios 7 下运行良好,但在为 iOS 8 构建时,展开转场无法正常工作。

我创建了一个新项目并添加了一个模态(带有 tableviewcontroller 的导航控制器)并尝试使用展开模态。不幸的是,它也不起作用。正在展开的方法位于目标视图控制器中。展开转场是通过情节提要(tableviewcontroller 中的导航栏按钮)创建的。当我点击按钮时,什么也没有发生。没有日志输出,模态也没有消失。它似乎也只影响模态序列。 push/popover 正常展开。

有没有人遇到过类似的问题并且有一个想法我该如何解决?

【问题讨论】:

我在几个地方也遇到过这个问题 - 我一直希望它会在正式发布时得到修复,但时间快到了! 您应该将您接受的答案更新为@Stewart Hou 的答案,因为它是唯一专门解决您的问题的答案。它还将帮助遇到相同问题的其他人找到正确的答案。 【参考方案1】:

Apple 已在 iOS 8.1 中修复了此错误

iOS 8.0 的临时解决方案

unwind segue 仅在下一种情况下不起作用:

视图结构:UITabBarController -> UINagivationController -> UIViewController1 -> UIViewController2

一般情况下(iOS 7、8.1),当从UIViewController2展开到UIViewController1时,会在UIViewController1中调用viewControllerForUnwindSegueAction /strong>。

然而在 iOS 8.0 和 8.0.x 中,它会在 UITabBarController 中调用 viewControllerForUnwindSegueAction 而不是 UIViewController1,这就是为什么 unwind segue 不再工作。

解决方案:通过创建自定义 UITabBarController 覆盖 UITabBarController 中的 viewControllerForUnwindSegueAction 并使用自定义的。 p>

对于斯威夫特

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
    


对于老式的 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

================================================ ================================

不要使用低于此点的任何解决方案(它们已过时,仅供参考)

9 月 23 日最新更新

我的新解决方案是推送到嵌入在导航控制器中的视图,并将导航控制器配置为在推送时隐藏底部栏(IB 中的复选框)。然后你会看到一个看起来像模态视图的视图,唯一不同的是推送和弹出的动画。您可以根据需要自定义

更新:下面的解决方案实际上是在标签栏下呈现了模态视图,这会导致进一步的视图布局问题。

将 segue 类型更改为 Present As Popover 仅适用于 iPhonesiOS8在 iOS7 上您的应用会崩溃。

同样,为了解决这个问题,我将 segue 的演示文稿设置为当前上下文(我的应用仅适用于 iphone)。

默认和全屏都不起作用。

【讨论】:

这几天我一直把头撞在墙上。这是最终奏效的解决方案。谢谢!现在可以在 XCode 6 中构建。 我在 iPad 上的所有模态序列都被破坏了,这也解决了我的问题。 将当前上下文设置为演示类型为我重新启用了展开序列。但是仍然有一些意想不到的行为。 大家好。我最新最好的解决方法:回到旧的委托方法!我使用 segue 打开弹出框或模式视图,并使用标准委托方法将其关闭。一切恢复正常! iOS 9 中是否有可能返回 8.0 错误?我的 unwind segue(带有 tabbarcontroller)在 iOS 8.1 上运行良好,但在 iOS 9 上停止运行......【参考方案2】:

[更新:修复了 iOS 8.1 测试版中的错误,但您需要它来支持 8.0 和 8.0.2]

我可以让我的放松继续工作的唯一方法是混合 Aditya 和 viirus 的答案。

我的设置进入: [View Controller 1] > 自定义模态 segue > [Navigation Controller] > root > [View Controller 2]

放松: [View Controller 2] > 自定义展开转场 > [View Controller 1]

修复: 子类化 [Navigation Controller],添加一个名为 sourceViewController 的属性,并在从 [View Controller 1] 转到 [Navigation Controller] 时调用准备 segue 时将“self”传递给该属性

在 [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];   

然后我在那个 [Navigation Controller] 子类中覆盖它,只是因为我有一个自定义展开 segue:

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

【讨论】:

唯一对我有用的解决方案,谢谢。就我而言,我使用的是具有类似设置的默认展开转场。 这会导致在 iOS 8 上调用 unwind 函数,但是在 iOS 7 上它不会自动关闭模态 VC。如果我以编程方式将其关闭,则在 iOS 7 上会记录一条消息:警告尝试在演示或关闭过程中从视图控制器中关闭!你是如何解决这个问题的?我不想检测操作系统,如果 iOS 8 则手动关闭。【参考方案3】:

这是 iOS 8.0、8.0.1 和 8.0.2 的问题。它在 8.1 中得到解决; unwind segues 现在正在调用适当的方法。

请注意,在 iOS 8 上,模态显示的视图控制器在执行展开转场时可能不会自动关闭,这与 iOS 7 不同。为确保它始终被关闭,您可以检测它是否被关闭,如果没有则手动关闭它。这些不一致在 iOS 9.0 中得到解决。

在 iPhone 上运行 iOS 8.4 后,所有呈现样式的所有模态呈现的 segue 在展开时都会消失,除了 Over Full Screen 和 Over Current Context。 iPad 也是如此,添加的表单和页面表也不会自动关闭。在 iOS 9 中,所有演示样式在 iPhone 和 iPad 上都会自动消失。

【讨论】:

您确定 not dismissing 是有意的并且不依赖于此错误吗? 我不肯定这是有意的还是其他错误@DavideDeFranceschi,我只是陈述了我看到的行为以及如何使它像在 iOS 7 上一样工作。 这是一个好消息,iOS 8.1 已修复此问题! 事实上,当以“当前”样式呈现视图控制器时,展开转场可以正常工作。但是,一旦您选择了另一种演示风格,例如“Over Full Screen”,那么展开 segue 就不会自动关闭视图控制器。您必须在 unwind segue 的主体中添加dismissViewController:animated:。【参考方案4】:

是的,这也发生在我身上,我认为对于您的情况,您必须继承 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];
    

【讨论】:

非常感谢!通过将 sourceViewController 变量添加到 Navigationcontroller 并在显示模式时在 prepareForSegue 调用中设置它,我设法让 segues 工作。 :) 在我希望展开的导航控制器中使用这个函数,我能够看到我希望展开的特定容器视图控制器没有被调用。我认为这就是我们在 iOS 8 中看到的变化 - 子容器视图控制器未包含在展开层次结构流中【参考方案5】:

同样的问题。未调用 Unwind 方法。只发生在

使用模态转场 演示不是“当前上下文” NavigationController 未扩展(使用故事板中的默认值)

IOS8 GM Seed 中也会发生这种情况,因此我认为我们需要找到一种解决方法。 对我来说听起来像是一个错误......

扩展 UINavigationController 和实现 viewControllerForUnwindSegueAction 没有帮助,因为它没有被触发。唯一被触发的是扩展 UINavigationController 中的 canPerformUnwindSegueAction()。奇怪。

【讨论】:

您确定 canPerformUnwindSegueAction 返回 YES 吗?对我来说,viewControllerForUnwindSegueAction 总是在子类 UINavigationController 中触发【参考方案6】:

哇!我仍然收到用户报告说卡在 iOS 8.1.1(在 iPad 3 上)的模式视图中。

我放弃了所有这些从模态视图中放松的东西。只是一个很好的老式...

[self dismissViewControllerAnimated:NO completion:nil];

...在所有这些不同的 iOS 8.x.x 版本上都可以正常工作。

【讨论】:

【参考方案7】:

iOS 7.1 和 iOS 8.1/8.2 似乎都从导航控制器创建了 unwind segue,但是 unwind segue 注册在导航控制器内的子控制器上。

因此,从在情节提要中注册的控制器手动创建展开转场可以解决问题。

@implementation RootNavigationController

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


@end

【讨论】:

【参考方案8】:

从目标视图控制器展开到源视图控制器时,我遇到了同样的问题。目的地是通过来源的“表演”转场呈现的。 我正在使用显示 iPhone 6、iOS8.3 的 iPhone 模拟器。 XCode 6.3.2

继承 NavigationViewController 的解决方案对我有用。这是 swift 代码,它本质上是 Raul 答案的快速翻译。我很困惑,如果 Apple 在 iOS8.1 中按 Raul 修复了它,我怎么会在 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)
    

【讨论】:

【参考方案9】:

我刚刚遇到了这个问题,经过一番挖掘后发现,使用模态 segues(至少具有默认和全屏演示模式的),你不能依赖正常的展开机制,而是你必须调用介绍了 UIViewController 的dismissViewControllerAnimated 方法。

【讨论】:

【参考方案10】:

要遵循的步骤:

    将展开转场链接到 Storyboard 中的按钮。

    为按钮创建 IBAction 并在其中添加以下代码:

    [self dismissViewControllerAnimated:NO completion:nil];
    

这应该适用于所有版本。

【讨论】:

以上是关于Unwind Segue 在 iOS 8 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

iOS 8 unwind segue 导致方向错误

适配 iOS 8 时遇到的问题两则:远程推送和 Unwind Segue

从 Unwind segue 触发时,Push segue 不起作用

Unwind segue 不起作用 SWIFT

在容器视图中导航时,Unwind Segue 不起作用

iOS开发使用Unwind Segue进行返回