【问题标题】:Calling performSeguewithIdentifier doesn't call shouldperformseguewithIdentifier调用 performSeguewithIdentifier 不会调用 shouldperformseguewithIdentifier
【发布时间】:2015-01-12 19:44:54
【问题描述】:

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

  • 将我带到 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)}
} 

【问题讨论】:

  • 嘿@es3dev,你能在我的回答中打勾吗? :)

标签: ios swift segue


【解决方案1】:

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

1) shouldPerformSegueWithIdentifier 用于确保触发已在 Storyboards 中设置的 segue,因此 只有在 Storyboard 的情况下才会调用它转场,让您有机会实际执行转场。

2) 当您自己调用performSegueWithIdentifier 时,shouldPerformSegueWithIdentifier 不会被调用,因为可以假定您知道自己在做什么。调用performSegueWithIdentifier 并从shouldPerformSegueWithIdentifier 返回NO 是没有意义的。

【讨论】:

  • 因此,如果是这种情况,则无法从 UIButton 设置我的 segue,因为即使我在 IBAction 中什么都不做,也会执行 segue。相反,segue 应该只是来自视图控制器......对吗?
  • 一旦你知道了答案,这很明显......现在感谢你,我知道了答案!谢谢!
【解决方案2】:

@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 和代码触发的 segue。

【讨论】:

  • 这是一个务实的解决方案。
  • 完美答案。并且是所有 VC 的必备解决方案。我将投入到我的 BaseVC 中,以便所有 VC 都能受益。事实上,使用“shouldPerformSegueWithIdentifier”,行数更短,segues可以通过编程和故事板在同一个VC中进行
【解决方案3】:

正如上面的答案。如果您调用performSegueWithIdentifier,则不会调用shouldPerformSegueWithIdentifier

举个例子:

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

在这种情况下需要shouldPerformSegueWithIdentifier

您可以设置一个布尔值,如果它的 false 返回 false 并且您的 segue 不会被触发,则您在 shouldPerformSegueWithIdentifier 中检查它。一旦你的应用下载了图片,你就可以调用 performSegueWithIdentifier

【讨论】:

    【解决方案4】:

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

    [self performSegueWithIdentifier:name sender:sender];

    【讨论】:

      【解决方案5】:

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

      要在performingSegue 之前强制调用shouldPerformSegue,您可以在类中覆盖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)
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-07-05
        • 1970-01-01
        • 1970-01-01
        • 2014-03-04
        • 2014-12-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多