ios 在prepareForSegue 方法中防止segue?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8066525/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 15:17:39  来源:igfitidea点击:

Prevent segue in prepareForSegue method?

ioscocoa-touchuiviewcontrollerstoryboardsegue

提问by Shmidt

Is it possible to cancel a segue in the prepareForSegue:method?

是否可以取消该prepareForSegue:方法中的 segue ?

I want to perform some check before the segue, and if the condition is not true (in this case, if some UITextFieldis empty), display an error message instead of performing the segue.

我想在 segue 之前执行一些检查,如果条件不正确(在这种情况下,如果 someUITextField为空),则显示错误消息而不是执行 segue。

回答by Abraham

It's possible in iOS 6 and later: You have to implement the method

在 iOS 6 及更高版本中是可能的:您必须实现该方法

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

In your view controller. You do your validation there, and if it's OK then return YES;if it's not then return NO;and the prepareForSegue is not called.

在您的视图控制器中。您在那里进行验证,如果可以,则return YES;如果不是return NO;,则不调用 prepareForSegue。

Note that this method doesn't get called automatically when triggering segues programmatically. If you need to perform the check, then you have to call shouldPerformSegueWithIdentifier to determine whether to perform segue.

请注意,以编程方式触发 segue 时,不会自动调用此方法。如果需要执行检查,则必须调用 shouldPerformSegueWithIdentifier 来确定是否执行 segue。

回答by Mike Mertsock

Note: the accepted answer is the best approach if you can target iOS 6. For targeting iOS 5, this answer will do.

注意:如果您可以针对 iOS 6,那么接受的答案是最好的方法。对于针对 iOS 5,这个答案就行了。

I don't believe it is possible to cancel a segue in prepareForSegue. I would suggest moving your logic to the point that the performSeguemessage is first sent.

我不相信在prepareForSegue. 我建议将您的逻辑移到performSegue消息首先发送的位置。

If you are using Interface Builder to wire up a segue directly to a control (e.g. linking a segue directly to a UIButton), then you can accomplish this with a bit of refactoring. Wire the segue to the view controller instead of a specific control (delete the old segue link, and then control-drag from the view controller itself to the destination view controller). Then create an IBActionin your view controller, and wire the control to the IBAction. Then you can do your logic (check for empty TextField) in the IBAction you just created, and decide there whether or not to performSegueWithIdentifierprogramatically.

如果您使用 Interface Builder 将 segue 直接连接到控件(例如,将 segue 直接链接到UIButton),那么您可以通过一些重构来完成此操作。将 segue 连接到视图控制器而不是特定控件(删除旧的 segue 链接,然后从视图控制器本身控制拖动到目标视图控制器)。然后IBAction在您的视图控制器中创建一个,并将控件连接到 IBAction。然后你可以在你刚刚创建的 IBAction 中执行你的逻辑(检查空的 TextField),并在那里决定是否以performSegueWithIdentifier编程方式。

回答by OrdoDei

Swift 3: func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool

Swift 3: func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool

Return value trueif the segue should be performed or falseif it should be ignored.

如果应该执行 segue,则返回值true,如果应该忽略它,则返回false

Example:

示例

var badParameters:Bool = true

override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
    if badParameters  {
         // your code here, like badParameters  = false, e.t.c
         return false
    }
    return true
}

回答by Kaolin Fire

Alternatively, it's somewhat bad behavior to offer a button that a user shouldn't press. You can leave the segue wired as stands, but start with the button disabled. Then wire the UITextField's "editingChanged" to an event on the view control ala

或者,提供一个用户不应该按下的按钮是一种不好的行为。您可以将 segue 有线作为支架,但从禁用按钮开始。然后将 UITextField 的“editingChanged”连接到视图控件 ala 上的事件

- (IBAction)nameChanged:(id)sender {
    UITextField *text = (UITextField*)sender;
    [nextButton setEnabled:(text.text.length != 0)];
}

回答by Zumry Mohamed

Its easy in the swift .

在 swift 中很容易。

override func shouldPerformSegueWithIdentifier(identifier: String,sender: AnyObject?) -> Bool {

    return true
}

回答by AechoLiu

As Abraham said,check valid or not in the following function.

正如亚伯拉罕所说,在以下函数中检查是否有效。

- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(nullable id)sender
{
     // Check this identifier is OK or NOT.
}

And, the performSegueWithIdentifier:sender:called by programming can be blocked by overwriting following method. By default, it is not checking valid or not by -shouldPerformSegueWithIdentifier:sender:, we can do it manually.

并且,performSegueWithIdentifier:sender:可以通过覆盖以下方法来阻止编程调用。默认情况下,它不检查是否有效-shouldPerformSegueWithIdentifier:sender:,我们可以手动进行。

- (void)performSegueWithIdentifier:(NSString *)identifier sender:(id)sender
{
    // Check valid by codes
    if ([self shouldPerformSegueWithIdentifier:identifier sender:sender] == NO) {
        return;
    }

    // If this identifier is OK, call `super` method for `-prepareForSegue:sender:` 
    [super performSegueWithIdentifier:identifier sender:sender];
}

回答by Swappyee

Should Perform Segue for Login Register

应该为登录注册执行 Segue

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

    [self getDetails];

    if ([identifier isEqualToString:@"loginSegue"])
    {

        if (([_userNameTxtf.text isEqualToString:_uname])&&([_passWordTxtf.text isEqualToString:_upass]))
        {

            _userNameTxtf.text=@"";
            _passWordTxtf.text=@"";

            return YES;
        }
        else
        {
            UIAlertView *loginAlert = [[UIAlertView alloc] initWithTitle:@"Alert" message:@"Invalid Details" delegate:self cancelButtonTitle:@"Try Again" otherButtonTitles:nil];

            [loginAlert show];

            _userNameTxtf.text=@"";
            _passWordTxtf.text=@"";

            return NO;
        }

    }

    return YES;

}

-(void)getDetails
{
    NSArray *dir=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    NSString *dbpath=[NSString stringWithFormat:@"%@/userDb.sqlite",[dir lastObject]];

    sqlite3 *db;

    if(sqlite3_open([dbpath UTF8String],&db)!=SQLITE_OK)
    {
        NSLog(@"Fail to open datadbase.....");
        return;
    }

    NSString *query=[NSString stringWithFormat:@"select * from user where userName = \"%@\"",_userNameTxtf.text];

    const char *q=[query UTF8String];

    sqlite3_stmt *mystmt;

    sqlite3_prepare(db, q, -1, &mystmt, NULL);

    while (sqlite3_step(mystmt)==SQLITE_ROW)
    {
        _uname=[NSString stringWithFormat:@"%s",sqlite3_column_text(mystmt, 0)];

        _upass=[NSString stringWithFormat:@"%s",sqlite3_column_text(mystmt, 2)];
    }

    sqlite3_finalize(mystmt);
    sqlite3_close(db);

}

回答by James Moore

Similar to Kaolin's answer is to leave the seque wired to the control but validate the control based on conditions in the view. If you're firing on table cell interaction then you also need to set the userInteractionEnabled property as well as disabling the stuff in the cell.

类似于 Kaolin 的答案是将序列连接到控件,但根据视图中的条件验证控件。如果您触发表格单元格交互,那么您还需要设置 userInteractionEnabled 属性以及禁用单元格中的内容。

For instance, I've got a form in a grouped table view. One of the cells leads to another tableView that acts as a picker. Whenever a control is changed in the main view I call this method

例如,我有一个分组表视图中的表单。其中一个单元格导致另一个旨在作为选择器的表格展示。每当主视图中的控件发生更改时,我都会调用此方法

-(void)validateFilterPicker
{
    if (micSwitch.on)
    {
        filterPickerCell.textLabel.enabled = YES;
        filterPickerCell.detailTextLabel.enabled = YES;
        filterPickerCell.userInteractionEnabled = YES;
        filterPickerCell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    }
    else
    {
        filterPickerCell.textLabel.enabled = NO;
        filterPickerCell.detailTextLabel.enabled = NO;
        filterPickerCell.userInteractionEnabled = NO;
        filterPickerCell.accessoryType = UITableViewCellAccessoryNone;
    }

}

回答by Pankaj Kulkarni

Swift 4 Answer:

斯威夫特 4 答案:

Following is Swift 4 implementation to cancel segue:

以下是取消转场的 Swift 4 实现:

override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
    if identifier == "EditProfile" {
        if userNotLoggedIn {
            // Return false to cancel segue with identified Edit Profile
            return false
        }
    }
    return true
}

回答by Bogdan Ustyak

The other way is to override method of tableView with willSelectRowAt and return nil if you don't want to show the segue. showDetails()- is some bool. In most cases should be implemented in data model being represented in cell with indexPath.

另一种方法是使用 willSelectRowAt 覆盖 tableView 的方法,如果您不想显示 segue,则返回 nil。 showDetails()- 是一些布尔值。在大多数情况下,应该在单元格中表示的数据模型中实现indexPath

 func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
        if showDetails() {
                return indexPath            
        }
        return nil
    }