是否可以取消prepareForSegue:方法中的segue ?
prepareForSegue:
我想在segue之前执行一些检查,如果条件不为真(在这种情况下,如果一些UITextField为空),则显示错误消息而不是执行segue。
UITextField
注意:如果你的目标是iOS 6,那么接受的答案是最好的方法。针对iOS 5,这个答案就可以了。
我不相信在prepareForSegue中可以取消一个segue。我建议将你的逻辑移到performSegue消息第一次发送的位置。
prepareForSegue
performSegue
如果你正在使用Interface Builder将segue直接连接到控件(例如,将segue直接链接到UIButton),那么你可以通过一些重构来完成这一点。将segue连接到视图控制器,而不是特定的控件(删除旧的segue链接,然后从视图控制器本身control-drag到目标视图控制器)。然后在视图控制器中创建IBAction,并将该控件连接到IBAction。然后你可以在刚刚创建的IBAction中执行你的逻辑(检查空TextField),并在那里决定是否以编程方式performSegueWithIdentifier。
UIButton
IBAction
performSegueWithIdentifier
另外,提供一个用户不应该按的按钮是一种坏行为。您可以将segue设置为stand,但在开始时禁用该按钮。然后将UITextField的“editingChanged”连接到视图控件上的一个事件
- (IBAction)nameChanged:(id)sender { UITextField *text = (UITextField*)sender; [nextButton setEnabled:(text.text.length != 0)]; }
与Kaolin的答案类似,将seque连接到控件,但根据视图中的条件验证控件。如果你在表格单元格交互上触发,那么你还需要设置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; } }
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
在视图控制器中。你在那里进行验证,如果OK,则return YES;,如果不OK,则return NO;, prepareForSegue不被调用。
return YES;
return NO;
注意,当以编程方式触发segue时,不会自动调用此方法。如果你需要执行检查,那么你必须调用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. }
并且,编程调用的performSegueWithIdentifier:sender:可以通过覆盖下面的方法来阻塞。默认情况下,它不会通过-shouldPerformSegueWithIdentifier:sender:检查是否有效,我们可以手动执行。
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]; }
如果需要执行segue,则返回值真正的;如果需要忽略segue,则返回值假。
例子:
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 }
showDetails()
indexPath
func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? { if showDetails() { return indexPath } return nil }
回答:
下面是Swift 4取消segue的实现:
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 }