[英]How to do something before unwind segue action?
我刚刚想出了什么是一个放松的segue以及如何使用它与这个问题的好答案。 非常感谢。
但是,这是一个像这样的问题:
假设在场景B中有一个按钮可以展开到场景A的一个按钮,在它被分割之前我想要做一些事情,比如将数据保存到数据库。 我在B.swift中为这个按钮创建了一个动作,但它似乎直接进入了场景A而没有采取指定的动作。
谁知道为什么或如何做到这一点?
谢谢。
您可以按照描述的方式执行此操作,也可以在要解除的viewController中使用prepareForSegue
覆盖函数:
@IBAction func actionForUnwindButton(sender: AnyObject) {
println("actionForUnwindButton");
}
要么...
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
println("prepareForSegue");
}
第一个例子就像你描述的那样。 该按钮连接到展开segue和Interface Builder中的按钮操作。 在segue动作之前将触发按钮动作。 也许您没有将操作连接到界面构建器中的按钮?
第二个示例使您可以访问segue的sourceViewController
和destinationViewController
,以防有用(您还可以在目标视图控制器中的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
故事板:
编辑2
您的演示项目显示了这种不工作。 不同之处在于您使用barButtonItem来触发操作,而我使用的是常规按钮。 barButtonItem失败,而常规按钮成功。 我怀疑这是由于消息传递顺序的差异(接下来是猜想,但符合观察到的行为):
(A)View Controller中的UIButton
ViewController的按钮接收touchupInside
- (1)向其方法发送动作
- (2)将segue展开动作发送到storyboard segue
收到的所有消息以及按此顺序执行的方法:
actionForUnwindButton
prepareForSegue
unwindToRed
(B)导航控制器工具栏中的UIBarButtonItem
工具栏buttonItem接收touchupInside
- (1)将segue展开动作发送到storyboard segue
- (2)(可能,然后)向viewController的方法发送动作
执行顺序是
prepareForSegue
unwindToRed
actionForUnwindButton
prepareForSegue
和unwind
收到的消息。 但是,由于viewSetroller在segue期间被销毁,因此actionForUnwindButton
消息被发送到nil。 因此它不会被执行,并且日志打印
prepareForSegue
unwindToRed
在(B)的情况下,viewController在方法到达之前被销毁,因此不会被触发
所以看来你的选择是......
(a)使用带动作的UIButton并展开segue
(b)使用prepareForSegue
触发您的操作,这将在viewController仍处于活动状态时以及segue发生之前触发。
(c)不要使用展开segue,只需使用按钮动作即可。 在action方法中,您可以通过在导航控制器上调用popToViewController
来“展开”。
顺便说一句,如果你在viewController上实现了一个toolBar(不使用导航控制器的工具栏),结果是相同的:首先触发segue,因此按钮操作失败。
如果你能够成功地执行unWind Segue。 然后在segue发生之前调用目标View Controller中的方法,您可以使用segue对象在源viewcontroller中执行您想要的任何操作。
- (IBAction)unwindToThisViewController:(UIStoryboardSegue *)unwindSegue
{
CustomViewController *vc = (CustomViewController*) unwindSegue.sourceViewController;
[vc performAnyMethod];
[vc saveData];
NSString *temp = vc.anyProperty;
}
如果你想在源控制器中使用你的逻辑,那么在场景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");
}
}
首先,您应该在prepareForSegue方法中调用send数据函数。
- (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];
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.