提问人:Imre Kelényi 提问时间:9/24/2012 最后编辑:max_Imre Kelényi 更新时间:3/24/2018 访问量:239163
Unwind segues 有什么用,你如何使用它们?
What are Unwind segues for and how do you use them?
问:
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
放松 segues 是如何工作的,它们可以用来做什么?
答:
展开 segue 用于“返回”到某个视图控制器,通过多个 segue,您可以从该控制器获得“当前”视图控制器。
想象一下,你有一个东西作为它的根视图控制器。现在,您可以使用推送 segue 到 .现在,导航控制器的数组中有 A 和 B,并且 B 是可见的。现在你以模式呈现。MyNavController
A
B
viewControllers
C
使用展开 segue,您现在可以从 to “返回”(即关闭模态呈现的视图控制器),基本上“撤消”模态 segue。你甚至可以一直放松到根视图控制器,撤消模态 segue 和推送 segue。C
B
A
放松 segues 可以很容易地回溯。例如,在 iOS 6 之前,关闭呈现的视图控制器的最佳做法是将呈现视图控制器设置为呈现的视图控制器的委托,然后调用自定义委托方法,然后关闭 presentedViewController。听起来很繁琐和复杂?确实如此。这就是为什么放松 segues 很好。
评论
dismissViewController:animated
dismissViewController:animated:
至于如何在 StoryBoard 中使用展开 segues......
步骤1)
转到要展开的视图控制器的代码,并添加以下内容:
Objective-C语言
- (IBAction)unwindToViewControllerNameHere:(UIStoryboardSegue *)segue {
//nothing goes here
}
请务必在 Obj-C 的 .h 文件中声明此方法
迅速
@IBAction func unwindToViewControllerNameHere(segue: UIStoryboardSegue) {
//nothing goes here
}
步骤2)
在故事板中,转到要从中展开的视图,只需将按钮或其他任何内容拖动到源视图右上角的橙色小“退出”图标即可。
现在应该有一个选项可以连接到“- unwindToViewControllerNameHere”
就是这样,当您的按钮被点击时,您的 segue 就会放松。
评论
简而言之
展开 segue(有时称为退出 segue)可用于在推送、模式或弹出框 segue 之间导航(就像您从导航栏中弹出导航项、关闭弹出框或关闭模式呈现的视图控制器一样)。最重要的是,您实际上不仅可以通过一个步骤,还可以通过一系列推送/模态/弹出窗口来放松,例如,通过一个展开操作“返回”导航层次结构中的多个步骤。
在执行展开 segue 时,需要指定一个操作,该操作是要展开到的视图控制器的操作方法。
目标-C:
- (IBAction)unwindToThisViewController:(UIStoryboardSegue *)unwindSegue
{
}
迅速:
@IBAction func unwindToThisViewController(segue: UIStoryboardSegue) {
}
在情节提要中创建展开 segue 时,将使用此操作方法的名称。此外,此方法在执行放卷 segue 之前调用。您可以从传递的参数中获取源视图控制器,以便与启动 segue 的视图控制器进行交互(例如,获取模式视图控制器的属性值)。在这方面,该方法具有与 的方法类似的功能。UIStoryboardSegue
prepareForSegue:
UIViewController
iOS 8更新:Unwind segue 还适用于 iOS 8 的自适应 segues,例如“显示”和“显示详细信息”。
一个例子
让我们有一个包含导航控制器和三个子视图控制器的故事板:
从 Green View Controller 中,您可以展开(导航回)到 Red View Controller。从蓝色到绿色,你可以放松到绿色,或者通过绿色放松到红色。要启用放卷,您必须将特殊操作方法添加到红色和绿色中,例如,这是红色的操作方法:
目标-C:
@implementation RedViewController
- (IBAction)unwindToRed:(UIStoryboardSegue *)unwindSegue
{
}
@end
迅速:
@IBAction func unwindToRed(segue: UIStoryboardSegue) {
}
添加操作方法后,可以通过按住控件将 Ctrl 拖动到“退出”图标,在情节提要中定义展开 segue。在这里,我们希望在按下按钮时从绿色放松到红色:
您必须选择要展开到的视图控制器中定义的操作:
您还可以从蓝色(在导航堆栈中“两步之遥”)放松到红色。关键是选择正确的放卷动作。
在执行放卷之前,将调用 action 方法。在示例中,我定义了一个从绿色和蓝色到红色的展开序列。我们可以通过 UIStoryboardSegue 参数在 action 方法中访问展开的源:
目标-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")
}
}
展开也通过推/模态 segue 的组合来工作。例如,如果我添加了另一个带有模态 segue 的 Yellow 视图控制器,我们只需一步即可从 Yellow 一直放松到 Red:
从代码中解脱出来
当您通过将某些内容拖动到视图控制器的“退出”符号来定义展开 segue 时,文档大纲中会出现一个新的 segue:
选择 segue 并转到 Attributes Inspector 将显示 “Identifier” 属性。使用它为您的 segue 提供唯一标识符:
在此之后,可以像任何其他 segue 一样从代码中执行展开 segue:
目标-C:
[self performSegueWithIdentifier:@"UnwindToRedSegueID" sender:self];
迅速:
performSegueWithIdentifier("UnwindToRedSegueID", sender: self)
评论
dismissViewControllerAnimated:completion:
popViewControllerAnimated:
dismissViewControllerAnimated:completion:
popViewControllerAnimated:
Swift iOS版:
第 1 步:在 MASTER 控制器视图中定义此方法。您要返回的:
//pragma mark - Unwind Seques
@IBAction func goToSideMenu(segue: UIStoryboardSegue) {
println("Called goToSideMenu: unwind action")
}
第 2 步:(故事板)右键单击您的 SLAVE/CHILD EXIT 按钮并选择“goToSideMenu”作为连接按钮的操作,您将单击该按钮返回您的 MASTER 控制器视图:
第 3 步:构建并运行...
我在这里的其他答案中没有看到提到的是,当你不知道最初的 segue 起源于哪里时,你如何处理解仓,这对我来说是一个更重要的用例。例如,假设您有一个帮助视图控制器 (H),您可以从两个不同的视图控制器(A 和 B)以模式方式显示该控制器:
A → H B → H
如何设置展开 segue 以便返回到正确的视图控制器?答案是,您在 A 和 B 中声明了同名的平仓操作,例如:
// put in AViewController.swift and BViewController.swift
@IBAction func unwindFromHelp(sender: UIStoryboardSegue) {
// empty
}
这样,展开将找到启动 segue 的视图控制器(A 或 B)并返回它。
换句话说,将展开操作视为描述segue的来源,而不是它要去的地方。
评论
例如,如果从 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 控制器 ( 您需要将退出按钮连接到 VC 的退出图标并将其连接到 unwindseague:
- Unwind Seague Completed -> viewControllerA 的 TextLabel 已更改。
评论