什么是Unwind segues以及如何使用它们?

时间:2012-09-24 08:57:09

标签: ios ios6 uistoryboard

iOS 6和Xcode 4.5有一个新功能,称为" Unwind Segue":

  

展开segues可以允许转换到故事板中现有的场景实例

除了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 segue如何工作以及它们可用于什么?

6 个答案:

答案 0 :(得分:1256)

在果壳中

展开segue (有时称为退出segue )可用于导航回推送,模态或弹出窗口(就像您从导航中弹出导航项一样)栏,关闭弹出窗口或解除模态显示的视图控制器)。除此之外,您实际上不仅可以通过一个推送/模态/弹出窗口来展开,例如,使用单个展开操作“返回”导航层次结构中的多个步骤。

当您执行展开segue时,您需要指定一个动作,这是您想要展开的视图控制器的动作方法。

目标C:

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

夫特:

@IBAction func unwindToThisViewController(segue: UIStoryboardSegue) {
}

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

iOS 8更新:展开segues也适用于iOS 8的自适应segue,例如 Show Show Detail

示例

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

enter image description here

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

目标C:

UIViewController

夫特:

@implementation RedViewController

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

@end

添加操作方法后,您可以通过控制拖动到“退出”图标来定义故事板中的展开segue。在这里,我们想要在按下按钮时从绿色中取消红色:

enter image description here

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

enter image description here

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

在执行展开segue之前,将调用action方法。在示例中,我从Green和Blue中定义了一个展开为红色的segue。我们可以通过UIStoryboardSegue参数访问action方法中的unwind源:

目标C:

@IBAction func unwindToRed(segue: UIStoryboardSegue) {
}

夫特:

- (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!");
    }
}

展开也可以通过推/模态段的组合来实现。例如。如果我添加另一个带有模态segue的黄色视图控制器,我们可以一步一步从黄色放松回到红色:

enter image description here

从代码中展开

当你通过控制拖动东西到视图控制器的Exit符号来定义展开segue时,文档大纲中会出现一个新的segue:

enter image description here

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

enter image description here

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

目标C:

@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")
    }
}

夫特:

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

答案 1 :(得分:166)

至于如何在StoryBoard中使用展开segue ...

步骤1)

转到您希望展开到的视图控制器的代码,然后添加:

目标C

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

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

夫特

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

第2步)

在故事板中,转到要放松的视图,只需将按钮中的segue拖动到源视图右上角的小橙色“EXIT”图标即可。

enter image description here

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

就是这样,当你按下按钮时,你的segue会放松。

答案 2 :(得分:46)

Unwind segue用于“返回”某个视图控制器,通过多个segues,您可以从中获取“当前”视图控制器。

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

使用展开segues,您现在可以从C“退回”到B(即解除模态显示的视图控制器),基本上“撤消”模态segue。您甚至可以一直放松回到根视图控制器A,撤消模态segue和push segue。

展开segues可以轻松回溯。例如,在iOS 6之前,解除显示的视图控制器的最佳做法是set the presenting view controller as the presented view controller’s delegate, then call your custom delegate method, which then dismisses the presentedViewController。听起来既麻烦又复杂?它是。这就是为什么放松segues很好。

答案 3 :(得分:33)

我在其他答案中没有看到的东西就是当你不知道最初的segue起源在哪里时你如何处理放松,对我来说这是一个更重要的用例。例如,假设您有一个帮助视图控制器( H ),您可以从两个不同的视图控制器模式显示( A B ):< / p>

A H
B H

如何设置展开segue以便返回正确的视图控制器?答案是您在 A B 中声明了一个名为的展开动作,例如:

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

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

换句话说,将展开动作视为描述segue来自的位置,而不是它将要去的地方。

答案 4 :(得分:23)

Swift iOS:

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

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

    println("Called goToSideMenu: unwind action")

}

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

enter image description here 第3步:构建并运行...

答案 5 :(得分: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"
            }
            
        }

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

enter image description here

  • Unwind Seague Completed - &gt; ViewController的TextLabel已更改。

enter image description here