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

Imr*_*nyi 579 ios uistoryboard ios6

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

展开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
Run Code Online (Sandbox Code Playgroud)

展开segue如何工作以及它们可以用于什么?

Imr*_*nyi 1264

简而言之

一个退绕SEGUE(有时称为出口SEGUE)可用于导航回通过推,模态或酥料饼塞格斯(仿佛你弹出从导航栏的导航项目,关闭了酥料饼或驳回模态呈现视图控制器).除此之外,您实际上不仅可以通过一个推送/模态/弹出窗口来展开,例如,使用单个展开动作"返回"导航层次结构中的多个步骤.

执行展开segue时,需要指定一个操作,该操作是要放松到的视图控制器的操作方法.

Objective-C的:

- (IBAction)unwindToThisViewController:(UIStoryboardSegue *)unwindSegue
{
}
Run Code Online (Sandbox Code Playgroud)

迅速:

@IBAction func unwindToThisViewController(segue: UIStoryboardSegue) {
}
Run Code Online (Sandbox Code Playgroud)

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

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

一个例子

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

在此输入图像描述

从Green View Controller,您可以放松(导航回)到Red View Controller.从Blue您可以放松到Green或Red via Green.要启用展开,您必须将特殊操作方法添加到红色和绿色,例如,这里是红色的操作方法:

Objective-C的:

@implementation RedViewController

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

@end
Run Code Online (Sandbox Code Playgroud)

迅速:

@IBAction func unwindToRed(segue: UIStoryboardSegue) {
}
Run Code Online (Sandbox Code Playgroud)

添加操作方法后,您可以通过控制拖动到"退出"图标来定义故事板中的展开segue.在这里,我们想要在按下按钮时从Green中解除Red:

在此输入图像描述

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

在此输入图像描述

您还可以从Blue(在导航堆栈中"两步之遥")放松到Red.关键是选择正确的展开动作.

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

Objective-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!");
    }
}
Run Code Online (Sandbox Code Playgroud)

迅速:

@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")
    }
}
Run Code Online (Sandbox Code Playgroud)

放卷也可以通过推/模态段的组合来实现.例如,如果我添加了另一个带有模态segue的黄色视图控制器,我们可以从黄色一路退回到Red,只需一步:

在此输入图像描述

从代码中解除

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

在此输入图像描述

选择segue并转到Attributes Inspector会显示"Identifier"属性.使用此选项为您的segue提供唯一标识符:

在此输入图像描述

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

Objective-C的:

[self performSegueWithIdentifier:@"UnwindToRedSegueID" sender:self];
Run Code Online (Sandbox Code Playgroud)

迅速:

performSegueWithIdentifier("UnwindToRedSegueID", sender: self)
Run Code Online (Sandbox Code Playgroud)

  • 当然可以.但是,如果您使用的是故事板,则展开segue通常可以用更少的代码实现相同的功能.实际上,现在您可以在不编写任何代码的情况下解除模态呈现的视图控制器.当然,从代码中关闭控制器是正确的做法仍然有很多种情况. (32认同)
  • 与`dismissViewControllerAnimated:completion:`或`popViewControllerAnimated:`相比的另一个优点是,您添加到要展开的视图控制器的方法被调用,因此您可以轻松地知道所呈现的视图控制器已完成,而无需进行向视图控制器呈现所呈现的视图控制器的代表. (17认同)
  • +1很棒的答案.它们听起来真的很好,但是不能像`dismissViewControllerAnimated:completion:`或`popViewControllerAnimated:`这样的方法实现同样的东西? (12认同)
  • 我可以建议一个小编辑吗?在"RedViewController.m"中放置 - (IBAction)unwindTRed:(UIStoryboardSegue*)unwindSegue并不是"显而易见",反过来,这在任何故事板的"任何"绿色退出按钮中都是普遍可用的.很棒的答案,现在我将把它用于其他问题.谢谢! (8认同)
  • 确保将您的操作方法添加到头文件中,否则Storyboard将无法了解. (7认同)
  • 放卷的另一个好处是,没有人能够遵循代码,所以它将永远保持不变:) (4认同)

Tra*_* M. 164

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

步骤1)

去为您希望视图控制器代码里放松身心,并添加此:

Objective-C的

- (IBAction)unwindToViewControllerNameHere:(UIStoryboardSegue *)segue {
    //nothing goes here
}
Run Code Online (Sandbox Code Playgroud)

一定要在Obj-C的.h文件中声明这个方法

迅速

@IBAction func unwindToViewControllerNameHere(segue: UIStoryboardSegue) {
    //nothing goes here
}
Run Code Online (Sandbox Code Playgroud)

第2步)

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

在此输入图像描述

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

就是这样,当您点击按钮时,您的segue将会放松.

  • 我发现使用Xcode 4.5及更早版本时,必须在头文件中声明IBAction.我不知道这是否仍然是真的. (5认同)
  • 是否可以在没有情节提要的情况下(即以编程方式)执行第2步?我的情节提要(界面生成器)被弄乱了,并且没有显示放松的问题(xcode错误)。 (2认同)

Yan*_*yer 47

展开segue用于"返回"某个视图控制器,通过多个segues,您可以从中获取"当前"视图控制器.

想象一下,你有东西MyNavControllerA它的根视图控制器.现在你使用推送segue B.现在导航控制器的viewControllers数组中有A和B ,B是可见的.现在你以C模态呈现.

随着开卷塞格斯,你现在可以放松"回"从CB(即解雇模态呈现视图控制器),基本上是"撤销"的模式SEGUE.您甚至可以一直放松回到根视图控制器A,撤消模态segue和push segue.

展开segues可以轻松回溯.例如,在iOS 6之前,解除显示的视图控制器的最佳做法是将呈现视图控制器设置为呈现的视图控制器的委托,然后调用自定义委托方法,然后解除presentViewController.听起来既麻烦又复杂?它是.这就是为什么放松segues很好.

  • 你可以从呈现的控制器中调用`dismissViewController:animated`.您不必委托它.当然,如果您需要传回数据,那么您需要委托或其他方法. (7认同)
  • 虽然您可以从呈现的控制器中调用`dismissViewController:animated:`,但最佳实践"确实是在呈现控制器上调用委托方法来为您执行此操作,正如Yang所提到的那样. (3认同)

sha*_*naw 33

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

AH
BH

如何设置展开segue以便返回正确的视图控制器?答案是您在AB中 使用相同的名称声明一个展开动作,例如:

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

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

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

  • 感谢您提供此信息,我一直在寻找这个. (2认同)
  • 提到此信息真的很棒,因为我已经实施了该解决方案,直到我在这里提出建议之前,什么都没有发生 (2认同)

Vin*_*shi 24

Swift iOS:

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

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

    println("Called goToSideMenu: unwind action")

}
Run Code Online (Sandbox Code Playgroud)

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

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