在解除segue行动之前该怎么办?

时间:2015-02-07 10:15:11

标签: ios swift unwind-segue

我刚刚想出了什么是一个放松的segue以及如何将它与this问题的答案一起使用。非常感谢。

然而,这是一个像这样的问题:

假设在场景B中有一个按钮可以展开到场景A的一个按钮,在它被分割之前我想要做一些事情,比如将数据保存到数据库。我在B.swift中为这个按钮创建了一个动作,但它似乎直接进入了场景A而没有采取指定的动作。

任何人都知道为什么或如何做到这一点?

谢谢。

3 个答案:

答案 0 :(得分:21)

您可以按照描述的方式执行此操作,也可以在要解除的viewController中使用prepareForSegue覆盖功能:

@IBAction func actionForUnwindButton(sender: AnyObject) {
    println("actionForUnwindButton");
}

...或

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    println("prepareForSegue");
}

第一个例子就像你描述的那样。该按钮连接到展开segue和Interface Builder中的按钮操作。在segue动作之前将触发按钮动作。也许您没有将操作连接到界面构建器中的按钮?

第二个示例让您可以访问segue的sourceViewControllerdestinationViewController,以防万一也很有用(您也可以在unwind segue'目标视图控制器)。

如果要延迟解开segue直到按钮的本地操作完成,您可以使用self.performSegueWithIdentifier直接从按钮操作调用segue(而不是在故事板中将其挂钩)(或遵循wrUS61的建议)

修改

你似乎对是否可以通过将按钮连接到展开segue和按钮动作来解决这个问题。我已经建立了一个像这样的小测试项目:

class BlueViewController: UIViewController {

    @IBAction func actionForUnwindButton(sender: AnyObject) {
        println("actionForUnwindButton");
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        println("prepareForSegue");
    }
}


class RedViewController: UIViewController {

    @IBAction func unwindToRed(sender: UIStoryboardSegue) {
        println("unwindToRed");
    }
}

BlueViewController有一个按钮,在故事板中连接到unwindToRed展开segue和actionForUnwindButton按钮。它还会覆盖prepareForSegue,因此我们可以记录播放顺序。

输出:

actionForUnwindButton
prepareForSegue
unwindToRed

故事板:

enter image description here

编辑2

您的演示项目显示此正在运行。不同之处在于您使用barButtonItem来触发操作,而我使用的是常规按钮。 barButtonItem失败,而常规按钮成功。我怀疑这是由于消息传递顺序的不同(接下来是猜想,但符合观察到的行为):

(A)View Controller中的UIButton

ViewController的按钮接收touchupInside
- (1)向其发出行动方法
- (2)将segue展开动作发送到故事板segue
收到的所有消息以及按此顺序执行的方法:

actionForUnwindButton
prepareForSegue
unwindToRed

(B)导航控制器工具栏中的UIBarButtonItem

工具栏buttonItem接收touchupInside
- (1)将segue展开动作发送到故事板segue
- (2)(可能,然后)将动作发送到viewController的方法

执行顺序是

prepareForSegue
unwindToRed
actionForUnwindButton
收到

prepareForSegueunwind条消息。但是,当在segue期间销毁viewController时,actionForUnwindButton消息被发送到nil。所以它没有被执行,日志打印

prepareForSegue
unwindToRed

在(B)的情况下,viewController在方法到达之前被销毁,因此不会被触发

所以看来你的选择是...... (a)使用带动作的UIButton并展开segue
(b)使用prepareForSegue触发您的操作,这将在viewController仍处于活动状态时以及在发生segue之前触发。 (c)不要使用展开segue,只需使用按钮动作即可。在动作方法中,您可以“放松”'通过在导航控制器上调用popToViewController

顺便说一下,如果你在viewController上实现了一个toolBar(不使用导航控制器的工具栏),结果是一样的:首先触发segue,所以按钮动作失败。

enter image description here

答案 1 :(得分:3)

如果你能够成功地执行unWind Segue。然后在segue发生之前调用目标View Controller中的方法,您可以使用segue对象在源视图控制器中执行任何操作。

- (IBAction)unwindToThisViewController:(UIStoryboardSegue *)unwindSegue
{
  CustomViewController *vc = (CustomViewController*) unwindSegue.sourceViewController;
  [vc performAnyMethod];
  [vc saveData];
  NSString *temp = vc.anyProperty;

}

如果你想在源控制器中使用你的逻辑,那么在场景B中实现prepareForSegue并从Storyboard>设置unWind segue Identifier。左视图层次结构面板>在场景B中退出。

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if([[segue identifier] isEqualToString:@"backToSource"])
    {
        NSLog(@"Going Back");

    }
}

答案 2 :(得分:2)

首先,您应该在prepareForSegue方法中调用发送数据函数。

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if([[segue identifier] isEqualToString:@"UnwindIdentifier"]) {
        // send data
    }
}

如果你不希望在从服务器获得响应之前让unwind segue发生,你应该覆盖

- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender

方法和return NO;。然后,当您通过调用以下方式获得服务器响应时,您可以手动执行segue:

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