调用performSeguewithIdentifier并不会调用shouldperformseguewithIdentifier

时间:2014-11-15 13:54:59

标签: ios swift segue

我有两个视图控制器。在视图controller1上,我有以下内容:

  • 带我到viewcontroller2的segue - 这个segue被命名为" showme"并附加到viewcontroller
  • UIButton的IBAction

在我的代码中,我有以下按钮按下操作

@IBAction func buttonPress(sender: AnyObject) {
    println("button pressed")
        performSegueWithIdentifier("showme", sender: self)
}

我也有以下方法:

override func shouldPerformSegueWithIdentifier(identifier: String?, sender: AnyObject?) -> Bool {
    println("Should performing....")
    return true
}   

由于某种原因,永远不会调用shouldPerformSegueWithIdentifier函数。但是,如果我直接在UIButton上将segue添加到ViewController2中。

我已经确认在我的按钮操作中调用它的方向是有效的(见下文),但这不是我理解的工作方式。 prepareforSegue也是如此..

@IBAction func buttonPress(sender: AnyObject) {
    println("button pressed")
    if (shouldPerformSegueWithIdentifier("showme", sender: self)){
        performSegueWithIdentifier("showme", sender: self)}
} 

5 个答案:

答案 0 :(得分:74)

这种行为非常自然,原因如下:

1)shouldPerformSegueWithIdentifier用于确保触发已在 Storyboards 中设置的segue,因此仅在的情况下调用它>故事板Segues ,让您有机会实际执行segue。

2)当您自己致电performSegueWithIdentifier时,shouldPerformSegueWithIdentifier 被调用,因为可以假设您知道自己在做什么。调用performSegueWithIdentifier然后从NO返回shouldPerformSegueWithIdentifier毫无意义。

答案 1 :(得分:28)

@nburk回答绝对正确。

但是我理解,在某些情况下,无论如何都会调用shouldPerformSegueWithIdentifier:sender:,在代码中调用performSegueWithIdentifier:sender:时也是如此。

例如,我们想做一些验证来决定是否执行segue,我们希望将这个逻辑保留在一个地方,而不是像以下那样重复所有地方条件:

if (self.shouldPerformSegue) {
     [self performSegueWithIdentifier:identifier sender:sender];
}

这可以轻松实现覆盖performSegueWithIdentifier:sender:,如下所示:

- (void)performSegueWithIdentifier:(NSString *)identifier sender:(id)sender
{
    if ([self shouldPerformSegueWithIdentifier:identifier sender:sender]) {
        [super performSegueWithIdentifier:identifier sender:sender];
    }
    // otherwise do nothing
}

- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
{
    return self.shouldPerformSegue;
}

通过这种方式,您可以使用shouldPerformSegueWithIdentifier:sender:来定义逻辑,以允许/拒绝IB和代码触发的segues。

答案 2 :(得分:3)

如上所述。如果您致电performSegueWithIdentifier,则不会调用shouldPerformSegueWithIdentifier

举个例子:

让我们假设您在容器视图中有一个嵌入的segue,以便显示一些可以滑过的图像。当VC加载时,嵌入的segue会立即被触发。但是,如果您必须从远程API下载图像,您的应用程序将崩溃,因为在嵌入的segue /容器视图中不会显示任何图像。

在这种情况下,需要shouldPerformSegueWithIdentifier

您可以设置一个布尔值,在shouldPerformSegueWithIdentifier中检查它是否为false,并且您的segue不会被触发。一旦您的应用程序下载了图像,您就可以调用performSegueWithIdentifier

答案 3 :(得分:0)

如果您正在使用此代码,则需要删除;

[self performSegueWithIdentifier:name sender:sender];

答案 4 :(得分:0)

感谢@tanzolone提供完美的解决方案。在 Swift 5 上重写代码。

要在shouldPerformSegue之前强行呼叫performingSegue,可以在课堂上覆盖performingSegue

override func performSegue(withIdentifier identifier: String, sender: Any?) {
    if shouldPerformSegue(withIdentifier: identifier, sender: sender) {
        super.performSegue(withIdentifier: identifier, sender: sender)
    }
}

override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
    // Your code (return true if you want to perform the segue)
}