简体   繁体   English

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

[英]How to do something before unwind segue action?

I've just figured out what is an unwind segue and how to use it with the great answers from this question. 我刚刚想出了什么是一个放松的segue以及如何使用它与这个问题的好答案。 Thanks a lot. 非常感谢。

However, here's a question like this: 但是,这是一个像这样的问题:

Let's say there is a button in scene B which unwind segues to scene A, and before it segues I want something to be done, such as saving the data to database. 假设在场景B中有一个按钮可以展开到场景A的一个按钮,在它被分割之前我想要做一些事情,比如将数据保存到数据库。 I created an action for this button in B.swift, but it seems it goes directly to scene A without taking the action appointed. 我在B.swift中为这个按钮创建了一个动作,但它似乎直接进入了场景A而没有采取指定的动作。

Anyone knows why or how to do this? 谁知道为什么或如何做到这一点?

Thank you. 谢谢。

You can do it the way you describe, or by using a prepareForSegue override function in the viewController you are unwinding from: 您可以按照描述的方式执行此操作,也可以在要解除的viewController中使用prepareForSegue覆盖函数:

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

or... 要么...

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

The first example is as you describe. 第一个例子就像你描述的那样。 The button is wired up to the unwind segue and to the button action in Interface Builder. 该按钮连接到展开segue和Interface Builder中的按钮操作。 The button action will be triggered before the segue action. 在segue动作之前将触发按钮动作。 Perhaps you didn't connect the action to the button in interface builder? 也许您没有将操作连接到界面构建器中的按钮?

The second example gives you have access to the segue's sourceViewController and destinationViewController in case that is also useful (you also get these in the unwind segue's function in the destination view controller). 第二个示例使您可以访问segue的sourceViewControllerdestinationViewController ,以防有用(您还可以在目标视图控制器中的unwind segue函数中获取这些内容)。

If you want to delay the unwind segue until the button's local action is complete, you can invoke the segue directly from the button action (instead of hooking it up in the storyboard) using self.performSegueWithIdentifier (or follow wrUS61's suggestion) 如果你想延迟解开segue直到按钮的本地动作完成,你可以使用self.performSegueWithIdentifier直接从按钮动作调用segue(而不是在故事板中挂钩)(或者按照wrUS61的建议)

EDIT 编辑

you seem to have some doubts whether you can work this by wiring up your button both to an unwind segue and to a button action. 你似乎对是否可以通过将按钮连接到展开segue和按钮动作来解决这个问题。 I have set up a little test project like this: 我已经建立了一个像这样的小测试项目:

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 has a button that is connected in the storyboard to BOTH the unwindToRed unwind segue AND the actionForUnwindButton button. BlueViewController有一个按钮,在故事板中连接到unwindToRed展开segue和actionForUnwindButton按钮。 It also overrides prepareForSegue so we can log the order of play. 它还会覆盖prepareForSegue因此我们可以记录播放顺序。

Output: 输出:

actionForUnwindButton
prepareForSegue
unwindToRed

Storyboard: 故事板:

在此输入图像描述

EDIT 2 编辑2

your demo project shows this not working. 您的演示项目显示了这种工作。 The difference is that you are using a barButtonItem to trigger the action, whereas I am using a regular button. 不同之处在于您使用barButtonItem来触发操作,而我使用的是常规按钮。 A barButtonItem fails, whereas a regular button succeeds. barButtonItem失败,而常规按钮成功。 I suspect that this is due to differences in the order of message passing (what follows is conjecture, but fits with the observed behaviour): 怀疑这是由于消息传递顺序的差异(接下来是猜想,但符合观察到的行为):

(A) UIButton in View Controller (A)View Controller中的UIButton

ViewController's button receives touchupInside ViewController的按钮接收touchupInside
- (1) sends action to it's method - (1)向其方法发送动作
- (2) sends segue unwind action to storyboard segue - (2)将segue展开动作发送到storyboard segue
all messages received, and methods executed in this order: 收到的所有消息以及按此顺序执行的方法:

actionForUnwindButton
prepareForSegue
unwindToRed

(B) UIBarButtonItem in Navigation Controller Toolbar (B)导航控制器工具栏中的UIBarButtonItem

Tool bar buttonItem receives touchupInside 工具栏buttonItem接收touchupInside
- (1) sends segue unwind action to storyboard segue - (1)将segue展开动作发送到storyboard segue
- (2) (possibly, then) sends action to viewController's method - (2)(可能,然后)向viewController的方法发送动作

Order of execution is 执行顺序是

prepareForSegue
unwindToRed
actionForUnwindButton

prepareForSegue and unwind messages received. prepareForSegueunwind收到的消息。 However actionForUnwindButton message is sent to nil as viewController is destroyed during the segue. 但是,由于viewSetroller在segue期间被销毁,因此actionForUnwindButton消息被发送到nil。 So it doesn't get executed, and the log prints 因此它不会被执行,并且日志打印

prepareForSegue
unwindToRed

In the case of (B), the viewController is destroyed before the method reaches it, so does not get triggered 在(B)的情况下,viewController在方法到达之前被销毁,因此不会被触发

So it seems your options are... 所以看来你的选择是......
(a) use a UIButton with action and unwind segue (a)使用带动作的UIButton并展开segue
(b) trigger your actions using prepareForSegue , which will be triggered while the viewController is still alive, and before the segue takes place. (b)使用prepareForSegue触发您的操作,这将在viewController仍处于活动状态时以及segue发生之前触发。
(c) don't use an unwind segue, just use a button action. (c)不要使用展开segue,只需使用按钮动作即可。 In the action method you can 'unwind' by calling popToViewController on your navigation controller. 在action方法中,您可以通过在导航控制器上调用popToViewController来“展开”。

By the way, if you implement a toolBar on the viewController (not using the navigation controller's toolbar) the result is the same: segue gets triggered first, so button action fails. 顺便说一句,如果你在viewController上实现了一个toolBar(不使用导航控制器的工具栏),结果是相同的:首先触发segue,因此按钮操作失败。

在此输入图像描述

If you are able to perform unWind Segue Successfully. 如果你能够成功地执行unWind Segue。 Then the method in destination View Controller is called just before the segue take place, you can do what ever you want in source viewcontroller by using the segue object. 然后在segue发生之前调用目标View Controller中的方法,您可以使用segue对象在源viewcontroller中执行您想要的任何操作。

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

}

if you want your logic in source Controller then implement prepareForSegue in Scene B and set the unWind segue Identifier from Storyboard > Left View hierarchy Panel > under Exit in Scene B. 如果你想在源控制器中使用你的逻辑,那么在场景B中实现prepareForSegue,并在场景B中的Exit下的Storyboard> Left View hierarchy Panel>中设置unWind segue Identifier。

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

    }
}

At first, you should call the send data function in prepareForSegue method. 首先,您应该在prepareForSegue方法中调用send数据函数。

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

If you don't want to let unwind segue happen before getting response from the server, you should override 如果你不希望在从服务器获得响应之前让unwind segue发生,你应该覆盖

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

method and return NO; 方法并return NO; . Then you can perform segue manually when you get the server response by calling: 然后,当您通过调用获得服务器响应时,您可以手动执行segue:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM