是否可以在 prepareForSegue: 方法中取消segue?
prepareForSegue:
我想在segue之前执行一些检查,如果条件不为真(在这种情况下,如果某些 UITextField 为空),则显示错误消息而不是执行segue .
UITextField
在iOS 6及更高版本中可以实现:您必须实现该方法
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
在您的视图控制器中 . 你在那里进行验证,如果没有问题,那么 return YES; 如果不是那么 return NO; 并且没有调用prepareForSegue .
return YES;
return NO;
请注意,在以编程方式触发segues时,不会自动调用此方法 . 如果需要执行检查,则必须调用shouldPerformSegueWithIdentifier来确定是否执行segue .
注意:如果您可以定位iOS 6,则接受的答案是最佳方法 . 对于iOS 5的定位,这个答案就可以了 .
我不相信有可能取消 prepareForSegue 中的segue . 我建议将你的逻辑移动到首先发送 performSegue 消息的程度 .
prepareForSegue
performSegue
如果您使用Interface Builder将segue直接连接到控件(例如将segue直接链接到 UIButton ),那么您可以通过一些重构来完成此操作 . 将segue连接到视图控制器而不是特定控件(删除旧的segue链接,然后从视图控制器本身控制拖动到目标视图控制器) . 然后在视图控制器中创建 IBAction ,并将控件连接到IBAction . 然后你可以在你刚刚创建的IBAction中执行你的逻辑(检查空TextField),并以编程方式决定是否 performSegueWithIdentifier .
UIButton
IBAction
performSegueWithIdentifier
Swift 3 :func shouldPerformSegue (withIdentifier identifier:String,sender:Any?) - > Bool
如果应该执行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 }
或者,提供用户不应按下的按钮会有些不好的行为 . 您可以将segue连接为支架,但从禁用按钮开始 . 然后将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 }
As Abraham said,在以下功能中检查是否有效 .
- (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]; }
应该登录注册登记
-(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); }
与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; } }
Swift 4答案:
以下是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 }
另一种方法是使用willSelectRowAt覆盖tableView的方法,如果你不想显示segue则返回nil . showDetails() - 是一些博尔 . 在大多数情况下,应该使用 indexPath 在单元格中表示的数据模型中实现 .
showDetails()
indexPath
func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? { if showDetails() { return indexPath } return nil }
10 回答
在iOS 6及更高版本中可以实现:您必须实现该方法
在您的视图控制器中 . 你在那里进行验证,如果没有问题,那么
return YES;
如果不是那么return NO;
并且没有调用prepareForSegue .请注意,在以编程方式触发segues时,不会自动调用此方法 . 如果需要执行检查,则必须调用shouldPerformSegueWithIdentifier来确定是否执行segue .
注意:如果您可以定位iOS 6,则接受的答案是最佳方法 . 对于iOS 5的定位,这个答案就可以了 .
我不相信有可能取消
prepareForSegue
中的segue . 我建议将你的逻辑移动到首先发送performSegue
消息的程度 .如果您使用Interface Builder将segue直接连接到控件(例如将segue直接链接到
UIButton
),那么您可以通过一些重构来完成此操作 . 将segue连接到视图控制器而不是特定控件(删除旧的segue链接,然后从视图控制器本身控制拖动到目标视图控制器) . 然后在视图控制器中创建IBAction
,并将控件连接到IBAction . 然后你可以在你刚刚创建的IBAction中执行你的逻辑(检查空TextField),并以编程方式决定是否performSegueWithIdentifier
.Swift 3 :func shouldPerformSegue (withIdentifier identifier:String,sender:Any?) - > Bool
如果应该执行segue,则返回值 true ;如果应该忽略,则返回 false .
Example :
或者,提供用户不应按下的按钮会有些不好的行为 . 您可以将segue连接为支架,但从禁用按钮开始 . 然后将UITextField的“editingChanged”连接到视图控件ala上的事件
它很容易在迅速 .
As Abraham said,在以下功能中检查是否有效 .
并且,编程调用的
performSegueWithIdentifier:sender:
可以通过覆盖以下方法来阻止 . 默认情况下,-shouldPerformSegueWithIdentifier:sender:
不会检查是否有效,我们可以手动执行 .应该登录注册登记
与Kaolin类似,答案是将seque连接到控件,但根据视图中的条件验证控件 . 如果您正在触发表格单元格交互,那么您还需要设置userInteractionEnabled属性以及禁用单元格中的内容 .
例如,我在分组表视图中有一个表单 . 其中一个单元格导致另一个tableView充当选择器 . 每当在主视图中更改控件时,我都会调用此方法
Swift 4答案:
以下是Swift 4实现取消segue:
另一种方法是使用willSelectRowAt覆盖tableView的方法,如果你不想显示segue则返回nil .
showDetails()
- 是一些博尔 . 在大多数情况下,应该使用indexPath
在单元格中表示的数据模型中实现 .