回答:
iOS 6以降で可能です:メソッドを実装する必要があります
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
あなたのView Controllerで。そこで検証を行います。問題がないreturn YES;
場合は、そうでなくreturn NO;
、prepareForSegueは呼び出されません。
このメソッドは、プログラムでセグエをトリガーするときに自動的に呼び出されないことに注意してください。チェックを実行する必要がある場合は、seguePerformSegueWithIdentifierを呼び出して、セグエを実行するかどうかを決定する必要があります。
if ([self shouldPerformSegueWithIdentifier:@"segueIdentifier" sender:nil]) { [self performSegueWithIdentifier:@"segueIdentifier" sender:nil]; }
注:iOS 6をターゲットにできる場合、受け入れられた回答が最良のアプローチです。iOS5をターゲットにすると、この回答で十分です。
でセグエをキャンセルすることはできないと思いますprepareForSegue
。performSegue
メッセージが最初に送信されるようにロジックを移動することをお勧めします。
Interface Builderを使用してセグエをコントロールに直接配線する場合(たとえば、セグエをに直接リンクするUIButton
場合)、少しのリファクタリングでこれを実現できます。特定のコントロールではなくビューコントローラーにセグエを配線します(古いセグエリンクを削除してから、ビューコントローラー自体から宛先のビューコントローラーにコントロールドラッグします)。次にIBAction
、ビューコントローラーでを作成し、コントロールをIBActionにワイヤリングします。次に、作成したIBActionでロジック(空のTextFieldを確認)を実行し、performSegueWithIdentifier
プログラムで行うかどうかを決定できます。
Swift 3:func shouldPerformSegue(withIdentifier identifier:String、sender:Any?)-> 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
}
または、ユーザーが押してはならないボタンを提供するのは、少し悪い動作です。セグエをそのまま配線したままにすることができますが、ボタンを無効にして開始します。次に、UITextFieldの「editingChanged」をビューコントロールalaのイベントにワイヤリングします。
- (IBAction)nameChanged:(id)sender {
UITextField *text = (UITextField*)sender;
[nextButton setEnabled:(text.text.length != 0)];
}
アブラハムが言ったように、次の関数で有効かどうかを確認します。
- (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
。
ログインレジスタのセグエを実行する必要があります
-(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プロパティも設定する必要があります。
たとえば、グループ化されたテーブルビューにフォームがあります。セルの1つは、ピッカーとして機能する別の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の実装です。
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
}
もう1つの方法は、テーブルビューのメソッドをwillSelectRowAtでオーバーライドし、セグエを表示したくない場合はnilを返すことです。
showDetails()
-いくつかのブールです。ほとんどの場合、でセルで表されるデータモデルに実装する必要がありますindexPath
。
func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
if showDetails() {
return indexPath
}
return nil
}