Answers:
在iOS 6和更高版本中可能:您必须实现方法
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
在您的视图控制器中。你做你的验证那里,如果是OK,然后return YES;
,如果它不是那么return NO;
与prepareForSegue不叫。
请注意,以编程方式触发segues时不会自动调用此方法。如果需要执行检查,则必须调用shouldPerformSegueWithIdentifier来确定是否执行segue。
if ([self shouldPerformSegueWithIdentifier:@"segueIdentifier" sender:nil]) { [self performSegueWithIdentifier:@"segueIdentifier" sender:nil]; }
注意:如果可以将iOS 6作为目标,则可接受的答案是最佳方法。对于iOS 5,可以使用此答案。
我不认为有可能取消的扣押prepareForSegue
。我建议将您的逻辑转移到performSegue
消息首次发送的地步。
如果您正在使用Interface Builder将连接直接连接到控件(例如,将连接直接链接到UIButton
),则可以通过一些重构来实现。将segue连接到视图控制器而不是特定控件(删除旧的segue链接,然后将控件从视图控制器本身拖动到目标视图控制器)。然后IBAction
在您的视图控制器中创建一个,并将控件连接到IBAction。然后,您可以在刚刚创建的IBAction中进行逻辑处理(检查是否有空的TextField),并在此确定是否以performSegueWithIdentifier
编程方式进行。
Swift 3:func shouldPerformSegue(withIdentifier标识符:字符串,发件人:任何?)-> 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, 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
}
正如亚伯拉罕所说,在以下功能中检查是否有效。
- (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];
}
[super performSegueWithIdentifier:identifier sender:sender];
真的是真的吗?
performSegueWithIdentifier:sender:
方法,而不调用它的super
方法。
应该为登录注册执行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);
}
与高岭土的答案类似,是将序列连接到控件,但根据视图中的条件验证控件。如果要触发表单元格交互,则还需要设置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的方法,如果不想显示顺序,则返回nil。
showDetails()
-是个布尔。在大多数情况下,应在以表示的单元格中的数据模型中实现indexPath
。
func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
if showDetails() {
return indexPath
}
return nil
}