Cocoa touch 如何排除在带有模态序列的UIStoryboard中呈现的模态?

Cocoa touch 如何排除在带有模态序列的UIStoryboard中呈现的模态?,cocoa-touch,uistoryboard,Cocoa Touch,Uistoryboard,设置:我有一个故事板设置,有两个简单的视图控制器a和B。a中有一个按钮,可以通过模式序列过渡到B。B在a的顶部有一个模态转换。这很好 问:有没有办法用一些简单的故事板魔术把B弹开,回到a 注意,如果这一切都在一个导航控制器中,并且我使用了一个push segue,那么它将由导航控制器隐式处理。会有一个“后退”按钮。modals没有可比性,我需要自己构建UI,这很好,但我想知道是否有一个segue机制可以用来指示从B返回a 现在,从B到A构建的oldskool方法是: 在B上创建委托属性 当模式

设置:我有一个故事板设置,有两个简单的视图控制器a和B。a中有一个按钮,可以通过模式序列过渡到B。B在a的顶部有一个模态转换。这很好

问:有没有办法用一些简单的故事板魔术把B弹开,回到a

注意,如果这一切都在一个导航控制器中,并且我使用了一个push segue,那么它将由导航控制器隐式处理。会有一个“后退”按钮。modals没有可比性,我需要自己构建UI,这很好,但我想知道是否有一个segue机制可以用来指示从B返回a

现在,从B到A构建的oldskool方法是:

  • 在B上创建委托属性
  • 当模式转换段回放时,将A设置为B的委托(我可以使用A的代码中的prepareforsgue:sender:钩住它)
  • 当该退出时,B向其代表发出信号
  • A实现了一个委托方法,该方法将取消B
这是可行的,但感觉开销太大,太傻了


是否有一些我错过的UIStoryboard机制,基本上可以执行“反向模态序列”?

没有任何脚本魔法可以在不编写一点代码的情况下关闭模态视图控制器

但是,虽然您确实需要实现自己的一些代码,但您不一定要遇到那么多麻烦。您只需在视图控制器B中有一个按钮,该按钮调用
[自解除视图控制器激活:是完成:否]
。(文档中说应该取消演示视图控制器,但他们也说,如果对演示者进行调用,消息将被转发到演示视图控制器。如果您想更明确地说明这一点,并且在某些情况下,例如当一个模态视图控制器从另一个视图控制器演示时,您需要这样做,您可以解释:请使用
self.presentingViewController
引用演示者,然后从那里调用
discouse…
。)

您可以在某些应用程序中看到代理业务,因为这是通知视图控制器A用户在视图控制器B中所做任何事情的一种方式。。。但这不是唯一的办法。有KVO、通知,或者在使用
self.presentingViewController
引用A的方法后直接调用A的方法(假设B知道它总是由A呈现)。如果A不需要知道在B中发生了什么(比如,因为用户点击了取消按钮),那么就不需要做任何事情——您只需取消模式,就可以完成它


在iOS 6及更高版本中,解绑分段添加了另一个选项,为解除模态视图控制器(或以其他方式“退出”一系列分段)提供了一点“情节提要魔法”。但这种方法仍然需要一些代码——您不能完全在情节提要中设置它。不过,从好的方面来看,该代码提供了一条路径,用于从被解除的视图控制器(B)到显示它的视图控制器(a)获取信息

苹果有详细的介绍,但以下是简短的版本:

  • 在要展开到的视图控制器类上定义一个
    iAction
    方法——表示模态视图控制器的类,而不是模态视图控制器本身(问题中的视图控制器a)。与正常的
    iAction
    方法不同,这些方法应采用
    UIStoryboardSegue*
    类型的参数;e、 g

    - (IBAction)unwindToMainMenu:(UIStoryboardSegue*)sender
    
  • 在显示的视图控制器(问题中的B)中,将控件连接到绿色退出图标,然后选择定义的方法

  • 在展开方法实现中,您可以参考segue的
    sourceViewController
    ,从要解除的视图控制器中检索信息。您不需要调用
    dismissViewControllerAnimated:completion:
    ,因为segue负责解除即将消失的视图控制器


  • 实现这一点有故事板魔法。这被称为放松阶段。在A的.h文件中,无论需要多少个展开段,都可以实现所需的任何“目标操作”样式的方法。对于模态,它通常是两个(取消和保存)。因此,在我的A.h文件中,我要添加:

    // A.h file
    - (IBAction)myCancelUnwindSegueCallback:(UIStoryboardSegue *)segue;
    - (IBAction)mySaveUnwindSegueCallback:(UIStoryboardSegue *)segue;
    
    现在,在你的故事板中,如果你有一个从a到B的序列。你现在可以做一个“目标动作”风格的控制,从你的取消/保存按钮拖动到故事板中B控制器底部的绿色“退出”图标。当您执行此操作时,Xcode将拾取我们创建的两个方法(因为它们位于A的头文件中,并且具有正确的签名(例如iAction和UIStoryboardSegue*),B是A序列的目标),因此,您就可以看到它了。你有你一直在寻找的故事板魔术

    在这两个回调的实现中,您会遇到如下情况:

    // A.m file
    - (IBAction)myCancelUnwindSegueCallback:(UIStoryboardSegue *)segue {
        UIViewController *modalGoingAway = segue.sourceViewController;
        // Do something (like get data) from modalGoingAway if you need to...
    }
    
    - (IBAction)mySaveUnwindSegueCallback:(UIStoryboardSegue *)segue {
        UIViewController *modalGoingAway = segue.sourceViewController;
        // Do something (like get data) from modalGoingAway if you need to...
    }
    

    最后,如果这种方法满足您的需求,那就太好了。你完了。但是,如果“on cancel”或“on save”我想在将控制权传递给A以从视图层次结构中删除B之前对B的私有属性执行一些操作,我仍然会连接整个协议委托/数据源设计模式。

    Cool,不知道presentingViewController(显然是一个新的iOS 5东西),这很有帮助。是的,如果你想把它放到一个自定义的segue中以便于重用,你可以做如下事情—(void)执行{UIViewController*src=(UIViewController*)self.sourceViewController;[src.presentingViewController dismissModalViewControllerAnimated:YES];}@SimonH关于segues的最好建议!此解决方案非常好,因为不需要为呈现的控制器创建子类
    UIViewController
    (所有代码都在呈现的控制器中)。一件小事:从Xcode 6.3.2(至少)开始,“退出”按钮不再是绿色的;)我不相信这个解决方案