Ios 在prepareForSegue方法中防止segue?

Ios 在prepareForSegue方法中防止segue?,ios,cocoa-touch,uiviewcontroller,storyboard,segue,Ios,Cocoa Touch,Uiviewcontroller,Storyboard,Segue,是否可以取消prepareforsgue:方法中的一段 我想在继续之前执行一些检查,如果条件不正确(在本例中,如果某些UITextField为空),则显示错误消息,而不是执行继续。注意:如果可以针对iOS 6,接受的答案是最佳方法。针对iOS 5,这个答案就行了 我认为不可能取消prepareforsgue中的一段。我建议将您的逻辑移动到第一次发送performsgue消息的位置 如果您使用Interface Builder将segue直接连接到控件(例如,将segue直接链接到UIButton

是否可以取消
prepareforsgue:
方法中的一段

我想在继续之前执行一些检查,如果条件不正确(在本例中,如果某些
UITextField
为空),则显示错误消息,而不是执行继续。

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

我认为不可能取消
prepareforsgue
中的一段。我建议将您的逻辑移动到第一次发送
performsgue
消息的位置


如果您使用Interface Builder将segue直接连接到控件(例如,将segue直接链接到
UIButton
),则您可以通过一些重构来实现这一点。将segue连接到视图控制器而不是特定控件(删除旧的segue链接,然后控制从视图控制器本身到目标视图控制器的拖动)。然后在视图控制器中创建一个
iAction
,并将控件连接到iAction。然后,您可以在刚刚创建的iAction中执行逻辑(检查空文本字段),并在那里决定是否以编程方式执行带有标识符的guemsguewithidentifier。

或者,提供一个用户不应该按下的按钮是有点不好的行为。您可以让segue保持连接状态,但首先禁用按钮。然后将UITextField的“editingChanged”连接到视图控件上的事件

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

与高岭土类似,高岭土的答案是将seque连接到控件,但根据视图中的条件验证控件。如果您正在启动表单元格交互,那么还需要设置userInteractionEnabled属性以及禁用单元格中的内容

例如,我在分组表视图中有一个表单。其中一个单元格指向另一个充当选择器的tableView。每当在主视图中更改控件时,我调用此方法

-(void)validateFilterPicker
{
如果(micSwitch.on)
{
filterPickerCell.textLabel.enabled=是;
filterPickerCell.detailTextLabel.enabled=是;
filterPickerCell.userInteractionEnabled=是;
filterPickerCell.accessoryType=UITableViewCellAccessoryDisclosureIndicator;
}
其他的
{
filterPickerCell.textLabel.enabled=否;
filterPickerCell.detailTextLabel.enabled=否;
filterPickerCell.userInteractionEnabled=否;
filterPickerCell.accessoryType=UITableViewCellAccessoryNone;
}
}

在iOS 6及更高版本中可以: 你必须实现这个方法

- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender 
在视图控制器中。您在那里进行验证,如果没有问题,则
返回YES如果不是,则
返回否且未调用prepareForSegue


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

应该为登录寄存器执行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);

}

在雨燕中很容易

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

    return true
}
在以下函数中检查有效或无效

- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(nullable id)sender
{
     // Check this identifier is OK or NOT.
}
并且,编程调用的
performsguewithidentifier: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];
}
Swift 3: func应执行segue(带标识符:字符串, 发送者:有吗?->Bool

如果应执行该序列,则返回值true;如果应忽略该序列,则返回值false

示例

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
}

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

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

以下是取消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
}

如果segue是一个popover控制器,您不希望再次点击按钮来创建另一个popover控制器;在这种情况下,正确的做法是关闭popover。你的回答考虑到了这种适当的行为。如果你直接从故事板上的按钮连接它,我看不出有什么合适的行为。在尝试让多个基于segue的popover一起很好地播放了几个小时后,我放弃了,放弃了popover序列,转而支持此解决方案。它实际上使用更少的代码。这会不会挫败使用segues的目的?将ViewController链接到ViewController的事实解决了我的问题。非常感谢。如果通过调用[self-performSegueWithIdentifier:@“segueIdentifier”发送方:nil]以编程方式触发segue,这是最佳解决方案供参考;ShouldPerformanceSegueWithIdentifier将永远不会被调用。@感谢您指出这一点。正在跟踪一个问题,但它没有达到我的断点。对于任何好奇的人,您只需要调用封装在if语句中的此方法即可获得相同的结果。@jpittman请您解释一下封装在if语句中是什么意思?@AubadaTaljo:(对格式化表示歉意)
if([self shoulldperformanceseguewithidentifier:@“segueinidentifier”sender:nil]){[self performSegueWithIdentifier:@“segueIdentifier”发送者:nil];}
在iOS 11.3 SDK中从情节提要segue中尝试了这一点,“shouldPerformSegueWithIdentifier”确实自动被调用“或者,提供一个用户不应该按下的按钮是有点不好的行为“我不同意这一点——这部分是正确的,但实际上取决于上下文。不引导用户也是一种不好的行为,例如,他们可以点击一个按钮,系统会解释首先需要做什么。使用禁用或不可见的按钮