601

iOS 6 和 Xcode 4.5 有一个称为“Unwind Segue”的新功能:

展开转场可以允许过渡到情节提要中的现有场景实例

除了 Xcode 4.5 发行说明中的​​这个简短条目之外,UIViewController 现在似乎有几个新方法:

- (BOOL)canPerformUnwindSegueAction:(SEL)action fromViewController:(UIViewController *)fromViewController withSender:(id)sender
- (UIViewController *)viewControllerForUnwindSegueAction:(SEL)action fromViewController:(UIViewController *)fromViewController withSender:(id)sender
- (UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(NSString *)identifier

unwind segues 是如何工作的,它们可以用来做什么?

4

6 回答 6

1285

简而言之

展开 segue(有时称为exit segue )可用于通过 push、modal 或 popover segue 向后导航(就像您从导航栏中弹出导航项、关闭弹出框或关闭模态呈现的视图控制器一样)。最重要的是,您实际上不仅可以通过一个,而且可以通过一系列推送/模态/弹出框来展开,例如,通过单个展开动作“返回”导航层次结构中的多个步骤。

当你执行一个 unwind segue 时,你需要指定一个 action,它是你想要 unwind 到的 view controller 的一个 action 方法。

目标-C:

- (IBAction)unwindToThisViewController:(UIStoryboardSegue *)unwindSegue
{
}

迅速:

@IBAction func unwindToThisViewController(segue: UIStoryboardSegue) {
}

当您在情节提要中创建展开转场时,将使用此操作方法的名称。此外,此方法在执行 unwind segue 之前调用。您可以从传递的UIStoryboardSegue参数中获取源视图控制器,以与启动 segue 的视图控制器进行交互(例如,获取模态视图控制器的属性值)。在这方面,该方法具有与 的prepareForSegue:方法类似的功能UIViewController

iOS 8 更新: Unwind segues 也适用于 iOS 8 的自适应 segues,例如ShowShow Detail

一个例子

让我们有一个带有导航控制器和三个子视图控制器的故事板:

在此处输入图像描述

从绿色视图控制器,您可以展开(导航返回)到红色视图控制器。从蓝色您可以放松到绿色或通过绿色到红色。要启用展开,您必须将特殊的操作方法添加到 Red 和 Green,例如,这里是 Red 中的操作方法:

目标-C:

@implementation RedViewController

- (IBAction)unwindToRed:(UIStoryboardSegue *)unwindSegue
{
}

@end

迅速:

@IBAction func unwindToRed(segue: UIStoryboardSegue) {
}

添加操作方法后,您可以通过控制拖动到退出图标来定义情节提要中的展开转场。在这里,我们想在按下按钮时从绿色放松到红色:

在此处输入图像描述

您必须选择要展开的视图控制器中定义的操作:

在此处输入图像描述

您还可以从蓝色放松到红色(在导航堆栈中“两步之遥”)。关键是选择正确的展开动作。

在执行 unwind segue 之前,会调用 action 方法。在示例中,我定义了从 Green 和 Blue 到 Red 的 unwind segue。我们可以通过 UIStoryboardSegue 参数在 action 方法中访问 unwind 的来源:

目标-C:

- (IBAction)unwindToRed:(UIStoryboardSegue *)unwindSegue
{
    UIViewController* sourceViewController = unwindSegue.sourceViewController;

    if ([sourceViewController isKindOfClass:[BlueViewController class]])
    {
        NSLog(@"Coming from BLUE!");
    }
    else if ([sourceViewController isKindOfClass:[GreenViewController class]])
    {
        NSLog(@"Coming from GREEN!");
    }
}

迅速:

@IBAction func unwindToRed(unwindSegue: UIStoryboardSegue) {
    if let blueViewController = unwindSegue.sourceViewController as? BlueViewController {
        println("Coming from BLUE")
    }
    else if let redViewController = unwindSegue.sourceViewController as? RedViewController {
        println("Coming from RED")
    }
}

展开也可以通过推/模态segues的组合来工作。例如,如果我添加另一个带有模态 segue 的 Yellow 视图控制器,我们可以一步从 Yellow 一直放松到 Red:

在此处输入图像描述

从代码中解脱出来

当您通过控制拖动某些东西到视图控制器的退出符号来定义展开转场时,文档大纲中会出现一个新的转场:

在此处输入图像描述

选择 segue 并转到 Attributes Inspector 会显示“Identifier”属性。使用它为您的 segue 提供唯一标识符:

在此处输入图像描述

在此之后,可以像任何其他 segue 一样从代码中执行展开 segue:

目标-C:

[self performSegueWithIdentifier:@"UnwindToRedSegueID" sender:self];

迅速:

performSegueWithIdentifier("UnwindToRedSegueID", sender: self)
于 2013-04-05T16:49:38.447 回答
169

至于如何在 StoryBoard 中使用 unwind segues ......

第1步)

转到您希望展开的视图控制器的代码并添加以下代码:

Objective-C

- (IBAction)unwindToViewControllerNameHere:(UIStoryboardSegue *)segue {
    //nothing goes here
}

请务必在 Obj-C 中的 .h 文件中声明此方法

迅速

@IBAction func unwindToViewControllerNameHere(segue: UIStoryboardSegue) {
    //nothing goes here
}

第2步)

在情节提要中,转到您要从中放松的视图,然后只需将一个 segue 从您的按钮或其他任何东西拖到源视图右上角的橙色小“退出”图标。

在此处输入图像描述

现在应该有一个连接到“-unwindToViewControllerNameHere”的选项

就是这样,当您的按钮被点击时,您的 segue 将展开。

于 2012-10-11T16:07:15.893 回答
46

展开转场用于“返回”到某个视图控制器,通过许多转场,您可以到达“当前”视图控制器。

MyNavController想象一下,你有一些 aA作为它的根视图控制器。现在你使用 push segue 到B. 现在导航控制器的viewControllers数组中有 A 和 B,并且 B 是可见的。现在您C以模态方式呈现。

使用展开转场,您现在可以从Cto展开“返回” B(即解除模态呈现的视图控制器),基本上“撤消”模态转场。您甚至可以一直回到根视图控制器A,撤消模态转场和推送转场。

Unwind segues 可以很容易地回溯。例如,在 iOS 6 之前,关闭呈现的视图控制器的最佳实践是将呈现的视图控制器设置为呈现的视图控制器的委托,然后调用您的自定义委托方法,然后关闭呈现的视图控制器。听起来繁琐复杂?它是。这就是为什么 unwind segues 很好的原因。

于 2012-10-02T12:43:40.513 回答
37

我在这里的其他答案中没有提到的一点是,当您不知道最初的转场起源于何处时,您如何处理展开,这对我来说是一个更重要的用例。例如,假设您有一个帮助视图控制器(H),您从两个不同的视图控制器(AB)模态显示:

AH
BH

你如何设置 unwind segue 以便回到正确的视图控制器?答案是您在AB中声明了一个 具有相同名称的展开操作,例如:

// put in AViewController.swift and BViewController.swift
@IBAction func unwindFromHelp(sender: UIStoryboardSegue) {
    // empty
}

这样,展开将找到启动 segue 的任何视图控制器(AB)并返回到它。

换句话说,将 unwind 动作视为描述 segue 来自哪里,而不是它要去哪里。

于 2015-12-15T19:33:59.063 回答
24

斯威夫特iOS:

第 1 步:将此方法定义到您的 MASTER 控制器视图中。你想回去的地方:

//pragma mark - Unwind Seques
@IBAction func goToSideMenu(segue: UIStoryboardSegue) {

    println("Called goToSideMenu: unwind action")

}

第 2 步:(故事板)右键单击您的 SLAVE/CHILD EXIT 按钮并选择“goToSideMenu”作为连接您的操作按钮,您将单击该按钮返回您的主控制器视图:

在此处输入图像描述 第 3 步:构建并运行...

于 2014-11-21T13:39:44.653 回答
1

例如,如果您从 viewControllerB 导航到 viewControllerA,那么在您的 viewControllerA 下面的委托将调用并共享数据。

@IBAction func unWindSeague (_ sender : UIStoryboardSegue) {
        if sender.source is ViewControllerB  {
            if let _ = sender.source as? ViewControllerB {
                self.textLabel.text = "Came from B = B->A , B exited"
            }
            
        }

}
  • Unwind Seague Source View Controller(您需要将Exit Button连接到VC的退出图标并将其连接到unwindseague:

在此处输入图像描述

  • Unwind Seague 已完成 -> viewControllerA 的 TextLabel 已更改。

在此处输入图像描述

于 2017-12-22T14:08:20.150 回答