如何以编程方式执行Unwind segue?


307

使用情节提要非常简单。您只需将操作拖到“退出”即可。但是,如何从代码中调用它呢?


33
我发现这是一个有效的问题–我自己回答过。您可以通过以下方式以编程方式执行取消序列:1.创建一个手动序列(从文件所有者的ctrl拖动到Exit),2.在IB中为其命名,然后3.在您的代码中执行常规的-performSegueWithIdentifier:sender:。
杨迈耶

6
不应关闭IMO。投票同意关闭此问题的用户肯定没有Obj-C / Cocoa Touch背景。
LJ威尔逊

杨:你怎么给它起个名字?
sarfata 2012年

我只用[self dismissViewControllerAnimated:YEScomplete:nil]; 以编程方式退出。我不知道这是不是正确的方法。
tangqiaoboy 2012年

1
sarfata:首先通过ctrl拖动从viewcontroller创建“ manual unwind segue”到“ Exit”。然后,您可以在文档大纲中找到序列。
huggie 2012年

Answers:


283
  1. 创建一个手动选择(ctrl从文件所有者拖至退出的-),
  2. 在绿色EXIT按钮下方的左侧控制器菜单中选择它。

在绿色EXIT按钮下方的左侧控制器菜单中选择它

插入Segue的名称以展开。

然后,- (void)performSegueWithIdentifier:(NSString *)identifier sender:(id)sender.与您的身份识别。


25
1)“文件的所有者”-那不是旧的术语吗?它对我来说可以控制从视图控制器到其“退出”图标的拖动。2)尽管应该很明显,但是Xcode正在IBAction的接口中寻找一个声明,该声明带有UIStoryboardSegue参数;WWDC 2012 407会议上没有提及此事,也没有将代码粘贴到其中。没有它,我的退出图标在拖动到控件时将不会激活。3)很酷的一点是,在大红色箭头的结尾处,在“动作”字段中,您可以单击“到达那里”箭头!
tobinjim

71
对于任何人谁像我一样,仍然有麻烦执行这个答案,我放在一起进行更彻底的演练和示例在此回购:github.com/bradley/iOSUnwindSegueProgramatically(不是想宣传我自己,我只是撞了我的头撞在墙上数小时,并看到工作设置对我
有所

3
@bradleygriffith您真是太棒了。感谢您的出色演练!
Eli_Rozen

7
@bradleygriffith我希望您能回答这个问题,以便我也能标出!您的独特贡献是确定哪个视图控制器获取什么代码。在任何地方都找不到。谢谢!
亚伦·威格2014年

3
对于仍然对此感到困惑的任何人,关键是IBACTION必须位于您要返回的视图控制器中,而不是您当前所在的视图控制器中。@ bradleygriffith在GitHub上进行了详细说明,但我没有看到在其他地方提到过。这部分至关重要。
Axeva 2014年

163

这是使用Objective C和Swift的完整答案:

1)IBAction在您的目标视图控制器(您想锁定到的位置)中创建一个放松的序列。实施文件中的任何位置。

// Objective C

    - (IBAction)unwindToContainerVC:(UIStoryboardSegue *)segue {

    }

// Swift

 @IBAction func unwindToContainerVC(segue: UIStoryboardSegue) {

    }

2)在源视图控制器(您正在从中进行选择的控制器)上,⌃ +从“活动名称”中拖动以退出。您应该在弹出窗口中看到在步骤1中创建的放松序列。(如果看不到,请复查第一步)。从弹出窗口中选择unwindToContainerVC:或您命名为将源控制器连接到展开IBAction的方法的任何名称。

在此处输入图片说明

3)在情节提要的源视图控制器的文档大纲中选择序列(它将在底部附近列出),并为其指定一个标识符

在此处输入图片说明

4)使用此方法从源代码视图控制器中调用放卷序列,替换您的放卷序列名称。

//目标C

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

//迅捷

self.performSegueWithIdentifier("unwindToContainerVC", sender: self)

注意 在unwind方法上使用segue参数的sourceViewController属性可访问源控制器上任何公开的属性。另外,请注意,该框架负责关闭源控制器。如果您想确认这一点,请向源控制器添加一个dealloc方法,并附带一条日志消息,该消息一旦被杀死,便会触发。如果dealloc不启动,您可能会有一个保留周期。


2
我的程序无法正常工作,甚至无法调用(IBAction)unwindToContainerVC:(UIStoryboardSegue *)segue
xhg 2015年

2
当您要平移的视图控制器仅存在于情节提要中时,此解决方案将不起作用,又在代码实现中没有自定义
mnl 2015年

@mnl不确定您要说的是什么,但是它适用于故事板场景或笔尖。如果要在代码中创建视图控制器场景,则不会使用任何以其名称“返回” IB的方法,由于这些方法用于在代码和IB之间进行通信,因此这实际上是无效的。那能解决您的意见吗?
smileBot 2015年

1
您的图片显示了ctrl+dragViewControllerExit极其有用。谢谢!
kbpontius

对于Swift 4.2,使用:self.performSegue(withIdentifier:“ unwindToVC”,发送者:self)
Reefwing

81

bradleygriffith的答案很好。我采取了第10步,并做了一个截图以简化操作。这是Xcode 6中的屏幕截图。

  1. 按住Control键从橙色图标拖动到红色“退出”图标可创建展开视图,而视图中没有任何操作/按钮。

在此处输入图片说明

  1. 然后unwind segue在侧边栏中选择:

在此处输入图片说明

  1. 设置一个Segue标识符字符串:

在此处输入图片说明

  1. 从代码访问该标识符:
[self performSegueWithIdentifier:@"unwindIdentifier" sender:self];

4
首先,展开方法必须包含在中UIViewController。然后您的解决方案将起作用
Alex Cio 2014年

5
并且您必须将标识符设置为这个新的segue!不要忘记它。
kraag22 2014年

1
是否可以以编程方式在源视图控制器中创建“退出”连接?
安德鲁·基尔纳

13

我用过的[self dismissViewControllerAnimated: YES completion: nil];它将使您返回到呼叫ViewController


6
Larry,如果您想返回到上一个视图控制器,即表示您正在退出的视图控制器,那是一种非常有效的方法。之所以出现这个问题,是因为Xcode 4.5中的新功能是能够从演示顺序中某个位置的一个视图控制器“展开”到更早的视图控制器。有关详细信息,请参见WWDC 2012会话407。
tobinjim

11

引用Apple的Unwind Segue技术注释中的文本:要添加只能以编程方式触发的Unwind Segue,请按住Control键并拖动将场景的视图控制器图标拖到其退出图标,然后从弹出菜单中为新的Segue选择一个Unwind操作。

链接到技术说明


6

Vishal Chaudhry的上述回答对我有用。我还添加了该命令,以便使用以下命令手动触发定居:

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

从ViewController中,还必须在情节提要中的ViewController的场景下选择展开序列,并且在RHS的属性视图中,确保Indentifier字段包含您在代码中引用的名称(在上面的示例中为“ mySegueName” )。

如果省略此步骤,则上面的行将引发一个例外,即不知道seque名称。


3

向后兼容的解决方案将对那些感兴趣的人适用于ios6之前的版本:

- (void)unwindToViewControllerOfClass:(Class)vcClass animated:(BOOL)animated {

    for (int i=self.navigationController.viewControllers.count - 1; i >= 0; i--) {
        UIViewController *vc = [self.navigationController.viewControllers objectAtIndex:i];
        if ([vc isKindOfClass:vcClass]) {
            [self.navigationController popToViewController:vc animated:animated];
            return;
        }
    }
}

2
放宽搜索功能比弹出导航控制器堆栈中的某个类要多得多。
史蒂夫·摩瑟

2

SWIFT 4

1.使用要在其中展开的控制器内部的segue 创建一个@IBAction

    @IBAction func unwindToVC(segue: UIStoryboardSegue) {

    }

2.在情节提要中,要从控制器中按ctrl +拖动(放开)控制器中的符号,以退出符号并选择您之前创建的方法:

在此处输入图片说明

3.现在您可以注意到,在文档大纲中,您有一个新行,标题为“ Unwind segue ....”。现在,您应该单击此行并打开属性检查器以设置标识符(在我的情况下为unwindSegueIdentifier)。

在此处输入图片说明

4.您快完成了!现在,您需要打开希望放松的视图控制器,并创建一些将执行segue的方法。例如,您可以添加按钮,使用@IBAction将其与代码连接,然后在此IBAction内添加perfromSegue(withIdentifier:sender :)方法:

     @IBAction func unwindToSomeVCWithSegue(_ sender: UIButton) {
         performSegue(withIdentifier: "unwindSegueIdentifier", sender: nil)
     }

这就是您要做的!


是否可以以编程方式在源视图控制器中创建“退出”连接?
安德鲁·基尔纳

1

Swift 4.2,Xcode 10以上

对于那些想知道如何使用未通过情节提要建立的 VC做到这一点的人(那些通过 “以编程方式” +“解开序曲”搜索来解决此问题的人)。

鉴于您无法以编程方式设置展开序列,最简单的纯编程解决方案是调用:

navigationController?.popToRootViewController(animated: true)

这会将堆栈中的所有视图控制器弹出回到您的根视图控制器。


要仅从导航堆栈中弹出最顶层的视图控制器,请使用:

navigationController?.popViewController(animated: true)


1
这通常比您想要的要多-只需弹出一下即可:[self.navigationController popViewControllerAnimated:YES];
安迪·温斯坦

确实,我已经在回答中添加了此内容-谢谢@AndyWeinstein
10623169

0

仅供参考:为了使@Vadim的答案与在View Controller中调用的手动展开固定动作配合使用,必须放置以下命令:

[self performSegueWithIdentifier:(NSString*) identifier sender:(id) sender];

在覆盖的类方法viewDidAppear中,如下所示:

-(void) viewDidAppear:(BOOL) animated
{
    [super viewDidAppear: animated];

    [self performSegueWithIdentifier:@"SomeSegueIdentifier" sender:self];
}

如果将其放在其他ViewController方法(如viewDidLoadviewWillAppear)中,它将被忽略。


3
绝对错误。随时随地都可以调用performSegueWithIdentifier。
smileBot

加载视图后,这不只是执行放松搜索吗?而不是在您想要的时间执行操作,例如在按下按钮后执行。
帕涅夫2014年

@Pahnev是的。我不知道这个答案如何得到支持。调用performSegueWithIdentfier确实做到了:从一个ViewController到另一个ViewController执行
序列化

完全错误。它将在启动时立即倒带。
Lee Probert
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.