Risposte:
È possibile in iOS 6 e versioni successive: devi implementare il metodo
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
Nel tuo controller di visualizzazione. Fai la tua validazione lì, e se è OK allora return YES;
se non lo è allora return NO;
e il readyForSegue non viene chiamato.
Si noti che questo metodo non viene chiamato automaticamente quando si innescano follower a livello di codice. Se è necessario eseguire il controllo, è necessario chiamare shouldPerformSegueWithIdentifier per determinare se eseguire segue.
if ([self shouldPerformSegueWithIdentifier:@"segueIdentifier" sender:nil]) { [self performSegueWithIdentifier:@"segueIdentifier" sender:nil]; }
Nota: la risposta accettata è l'approccio migliore se puoi scegliere come target iOS 6. Per il targeting iOS 5, questa risposta farà.
Non credo sia possibile annullare un seguito prepareForSegue
. Suggerirei di spostare la tua logica al punto in cui il performSegue
messaggio viene inviato per la prima volta.
Se stai usando Interface Builder per collegare un seguito direttamente a un controllo (ad esempio collegando un seguito direttamente a un UIButton
), puoi farlo con un po 'di refactoring. Collegare i seguenti al controller della vista anziché a un controllo specifico (eliminare il vecchio collegamento segue, quindi trascinare il controllo dal controller della vista stesso al controller della vista di destinazione). Quindi crea un IBAction
controller nella vista e collega il controllo a IBAction. Quindi puoi fare la tua logica (controlla TextField vuoto) nell'IBAction che hai appena creato, e decidere lì se performSegueWithIdentifier
programmarlo.
Swift 3 : func shouldPerformSegue (withIdentifier identifier: String, mittente: Any?) -> Bool
Restituisce il valore vero se il seguito deve essere eseguito o falso se deve essere ignorato.
Esempio :
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
}
In alternativa, è un comportamento un po 'brutto offrire un pulsante che un utente non dovrebbe premere. Puoi lasciare il seguito cablato come supporto, ma inizia con il pulsante disabilitato. Quindi collegare "editingChanged" di UITextField a un evento sull'ala di controllo della vista
- (IBAction)nameChanged:(id)sender {
UITextField *text = (UITextField*)sender;
[nextButton setEnabled:(text.text.length != 0)];
}
È facile in fretta.
override func shouldPerformSegueWithIdentifier(identifier: String,sender: AnyObject?) -> Bool {
return true
}
Come ha detto Abraham, controlla valido o meno nella seguente funzione.
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(nullable id)sender
{
// Check this identifier is OK or NOT.
}
E, il performSegueWithIdentifier:sender:
richiamo dalla programmazione può essere bloccato sovrascrivendo il seguente metodo. Per impostazione predefinita, non sta controllando valido o no -shouldPerformSegueWithIdentifier:sender:
, possiamo farlo manualmente.
- (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];
davvero vera?
performSegueWithIdentifier:sender:
metodo e non lo si chiama super
metodo.
Dovrebbe eseguire Segue per il registro di accesso
-(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);
}
Simile alla risposta di Kaolin è lasciare il seque collegato al controllo ma convalidare il controllo in base alle condizioni nella vista. Se stai attivando l'interazione tra celle della tabella, devi anche impostare la proprietà userInteractionEnabled e disabilitare gli elementi nella cella.
Ad esempio, ho un modulo in una vista tabella raggruppata. Una delle celle conduce a un altro tableView che funge da selettore. Ogni volta che un controllo viene modificato nella vista principale, chiamo questo metodo
-(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 Risposta:
Di seguito è l'implementazione di Swift 4 per annullare 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
}
L'altro modo è quello di sovrascrivere il metodo di tableView con willSelectRowAt e restituire zero se non si desidera mostrare il seguito.
showDetails()
- è un po 'bool. Nella maggior parte dei casi dovrebbe essere implementato nel modello di dati rappresentato in cella con indexPath
.
func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
if showDetails() {
return indexPath
}
return nil
}