2012-03-16 60 views
32

安装程序:我有一个故事板设置,有两个简单的视图控制器A和B. A中有一个按钮,通过模态渐变过渡到B. B在A之上呈现模态转换。它很好。如何解除用模态segue呈现在UIStoryboard中的模态?

问题:有没有一种方法可以让B离开并用一些简单的故事板魔法回到A?

请注意,如果这全部都在导航控制器中,并且我使用了推入塞格,那么它将隐式地由导航控制器处理。会有一个“后退”按钮。没有什么可比的模式,我需要自己建立UI,这很好,但我想知道是否有一个可以用信号从B回到A的信号机制。

现在使用oldskool方法构建的B回到A将是:

  • 基于B创建一个委托财产
  • 集A是B的代表时,模式转变SEGUE回放(我可以挂接到这一点使用prepareForSegue:发件人:在A的代码)
  • 当它是时候解雇,B信号给它的代表
  • A实现了一个委托方法,即解散B

这可行,但感觉像太多的开销和愚蠢。

是否有一些UIStoryboard机制,我错过了,基本上会做一个“反向模态赛格”?

回答

44

有没有任何故事板魔术解除一个模态视图控制器没有写至少一点点的代码。

但是,虽然你必须实现自己的一些代码,你不一定要去那么多麻烦。您可以在视图控制器B中只有一个调用[self dismissViewControllerAnimated:YES completion:nil]的按钮。 (文档中说,呈现视图控制器应该是一个可以解散的视图控制器,但是他们也会说,如果被邀请者被调用,该消息将被转发给呈现视图控制器。如果你想更清楚地了解它 - 会需要在某些情况下,当一个模态视图控制器从另一个呈现喜欢 - 你可以明确地从那里引用主持人与self.presentingViewController并调用dismiss...

您在一些应用程序看到的委托业务,因为它是一个。在视图控制器B中关于用户所做的任何事情通知视图控制器A的方式......但这不是唯一的方法。有KVO,通知,或简单地调用A的方法后引用self.presentingViewController(假设B知道它总是由A呈现)。如果A不需要知道B中发生了什么(例如,因为用户点击取消按钮),则无需执行任何操作 - 您可以关闭模​​式并完成相应操作。


在iOS 6中和以后,放松塞格斯添加另一种选择,提供的“故事板魔术”一点点解雇模态视图控制器(或以其他方式塞格斯的序列的“回退”)。但是这种方法仍然需要一些代码 - 你无法完全在故事板中进行设置。尽管如此,从代码的角度来看,从视图控制器获取信息被解散(B)到提供信息的途径(A)。

苹果a tech note about unwind segues覆盖它们的细节,但这里的短版本:

  1. 定义你想放松视图控制器类的IBAction方法 - 呈现一个模式的一个视图控制器,而不是模态视图控制器本身(视图控制器在你的问题)。与正常的IBAction方法不同,这些方法应采用UIStoryboardSegue *类型的参数;例如

    - (IBAction)unwindToMainMenu:(UIStoryboardSegue*)sender 
    
  2. 在所提出的视图控制器(在问题B),金属丝的控制绿色退出图标,然后选择你定义的方法。

  3. 在您的展开方法实现中,您可以参考segue的sourceViewController来从视图控制器中检索被解散的信息。您无需致电dismissViewControllerAnimated:completion:,因为segue可以解除正在消失的视图控制器。

+0

很酷,不知道呈现ViewController(显然是一个新的iOS 5的东西),这有助于。 – Jaanus 2012-03-16 06:28:23

+2

是的,如果你想将它作为一个自定义的继续以方便重用,你可以做一些类似于 - (void)执行{UIViewController * src =(UIViewController *)self.sourceViewController; [src.presentingViewController dismissModalViewControllerAnimated:YES]; } – AppHandwerker 2012-08-10 14:02:58

+0

@SimonH关于segues的最佳建议! – 2012-10-06 21:19:13

30

故事板魔法来实现这一目标。它被称为放松赛。在A的.h文件中,您可以实现所需的任何“目标动作”风格方法,但无论您需要多少放松方式。对于一个模式,通常是两个(取消和保存)。所以在我的文件啊我要补充:

// A.h file 
- (IBAction)myCancelUnwindSegueCallback:(UIStoryboardSegue *)segue; 
- (IBAction)mySaveUnwindSegueCallback:(UIStoryboardSegue *)segue; 

现在,在你的故事板,如果你从A到B.现在,您可以从您的取消/保存按钮做了“目标行动”的风格控制拖动SEGUE在B中到故事板中B控制器底部的绿色“退出”图标。当你这样做的时候,Xcode会选择我们创建的两个方法(因为它们在A的头文件中,并且它们有正确的签名(例如IBAction和UIStoryboardSegue *),而B是来自A的segue的目的地)你有它。你有你想要的故事板魔法!

在两个回调的实现,你会的东西,如:

// 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... 
} 

最后,如果这种方法满足你的需求,伟大的。你完成了。但是,如果“取消”或“保存”时我仍然连线整个协议委托/数据源设计模式,我希望在将控制权交给A以将B从视图层次结构中移除之前,对B的私有属性执行一些操作。

+1

请注意2件事: 1)在回调中,没有必要关闭模式,因为它会被自动解除顺序继续(如果你尝试,会导致错误) 2)解除继续动作(绿色退出按钮)与iOS6一起使用目标。它有点令人困惑,因为对于较老的目标,你会看到绿色的退出按钮,这是没有意义的) – 2014-02-02 12:05:56

+1

这不是真正的完整的“故事板魔法”,因为你仍然需要向你的A视图控制器添加代码。但就我而言,B只是静态内容,所以这不得不创建一个B视图控制器子类来解雇它。 – jab 2014-03-08 23:27:42