简体   繁体   English

调用performSeguewithIdentifier不会调用应该执行seguewithIdentifier

[英]Calling performSeguewithIdentifier doesn't call shouldperformseguewithIdentifier

I have two view controllers. 我有两个视图控制器。 On view controller1 I have the following: 在视图controller1上,我有以下内容:

  • a segue that takes me to viewcontroller2 - this segue is named "showme" and is attached to the viewcontroller 将我带到viewcontroller2的segue-此segue名为“ showme”,并附加到viewcontroller
  • an IBAction for a UIButton UIButton的IBAction

In my code I have the following for the button press action 在我的代码中,按钮按下操作具有以下内容

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

I also have the following method: 我也有以下方法:

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

For some reason the shouldPerformSegueWithIdentifier function is never called. 由于某些原因,从不调用shouldPerformSegueWithIdentifier函数。 If however, I add the segue directly on the UIButton to ViewController2 it is. 但是,如果我直接在UIButton上将segue添加到ViewController2。

I have confirmed that calling it direction within my button action works (see below), but this is not what I understand to be the way it works. 我已经确认在按钮操作中将其称为“方向”是可行的(请参见下文),但这不是我所理解的那样。 The same is true for prepareforSegue.. prepareforSegue也是如此。

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

This behaviour is perfectly natural, for the following reasons: 此行为是完全自然的,原因如下:

1) shouldPerformSegueWithIdentifier is used to make sure that a segue that has been set up in Storyboards should be triggered, so it only gets called in the case of Storyboard Segues and gives you the chance to not actually perform the segue. 1) shouldPerformSegueWithIdentifier用于确保应该触发在情节提要中设置的segue,因此仅在情节提要Segues的情况下才调用它,并且使您有机会实际执行此segue。

2) When you call performSegueWithIdentifier yourself, shouldPerformSegueWithIdentifier is not called because it can be assumed that you know what you are doing. 2)当你调用performSegueWithIdentifier自己, shouldPerformSegueWithIdentifier 叫,因为它可以假设你知道你在做什么。 There would be no point in calling performSegueWithIdentifier but then return a NO from shouldPerformSegueWithIdentifier . 调用performSegueWithIdentifier毫无意义,但是从shouldPerformSegueWithIdentifier返回NO

@nburk answer is absolutely correct. @nburk的答案是绝对正确的。

However I understand that in some situations it could be useful if shouldPerformSegueWithIdentifier:sender: would be called anyway, also when a call to performSegueWithIdentifier:sender: is made in code. 但是我知道,在某些情况下,无论如何都应该调用shouldPerformSegueWithIdentifier:sender:可能也是有用的,而且在代码中对performSegueWithIdentifier:sender:的调用也是如此。

For instance we want to make some validations to decide whether performing a segue or not and we want to keep this logic in a single place and not duplicating all over the place conditions like the following: 例如,我们要进行一些验证来决定是否执行序列,并且希望将此逻辑保留在单个位置,而不是像以下那样在所有位置条件下重复:

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

This can be easily achieved overriding performSegueWithIdentifier:sender: as follows: 可以很容易地通过覆盖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;
}

This way you can use shouldPerformSegueWithIdentifier:sender: to define your logic to allow/deny both IB and code triggered segues. 这样,您可以使用shouldPerformSegueWithIdentifier:sender:定义允许/拒绝IB和代码触发的序列的逻辑。

As the answer above. 作为上面的答案。 If you call performSegueWithIdentifier then shouldPerformSegueWithIdentifier is not called. 如果调用performSegueWithIdentifier shouldPerformSegueWithIdentifier调用shouldPerformSegueWithIdentifier

As an example: 举个例子:

Lets say you have an embedded segue inside a container view in order to show some images that you can swipe through. 假设您在容器视图中有一个嵌入式segue,以便显示一些可以滑动的图像。 And embedded segues gets fired right away when you VC has loaded. 当您加载VC时,嵌入式segue会立即被触发。 But if you would have to download the images from an remote API your app would crash since there wouldnt be any images to display in the embedded segue/container view. 但是,如果您必须从远程API下载图像,则由于嵌入的segue / container视图中不会显示任何图像,因此应用程序将崩溃。

In this case shouldPerformSegueWithIdentifier would be needed. 在这种情况下,将需要shouldPerformSegueWithIdentifier

You could setup a boolean value that you check in shouldPerformSegueWithIdentifier if its false return false and your segue wont be fired. 您可以设置一个布尔值,如果它的false返回false并且不会触发您的segue, shouldPerformSegueWithIdentifiershouldPerformSegueWithIdentifier检入。 And once your app has downloaded the images you could call performSegueWithIdentifier 一旦您的应用下载了图像,就可以调用performSegueWithIdentifier

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

[self performSegueWithIdentifier:name sender:sender];

Thanks @tanzolone for the perfect solution. 感谢@tanzolone提供完美的解决方案。 Rewrote code on Swift 5 . Swift 5上重写代码。

To forcefully call shouldPerformSegue before performingSegue , you can override performingSegue in you class: 要大力呼吁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)
}

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

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