在prepareForSegue方法中防止segue?

是否有可能取消prepareForSegue:方法中的segue?

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

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

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

在你的视图控制器。 你在那里做你的validation,如果没问题,那么return YES; 如果不是return NO; 并且prepareForSegue不是呼叫。

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

注意:如果您可以定位iOS 6,则接受的答案是最好的方法。对于定位iOS 5,此答案将会执行。

我不相信有可能在prepareForSegue取消一个segue。 我build议把你的逻辑转移到performSegue消息首先发送的地步。

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

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

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

它很容易在迅速。

 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. } 

而且,编程调用的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]; } 

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

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

例如

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

应该执行login注册

 -(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); } 

与高岭土的答案类似,将剩余线连接到控件,但根据视图中的条件validation控件。 如果您正在触发表格单元格交互,则还需要设置userInteractionEnabled属性以及禁用单元格中的内容。

例如,我有一个表格分组表格视图。 其中一个单元格导致另一个充当选取器的tableView。 每当在主视图中更改控件时,我都会调用这个方法

 -(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; } } 

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

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