Réponses:
C'est possible dans iOS 6 et versions ultérieures: vous devez implémenter la méthode
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
Dans votre contrôleur de vue. Vous faites votre validation là-bas, et si c'est OK alors return YES;
si ce n'est pas le cas return NO;
et que prepareForSegue n'est pas appelé.
Notez que cette méthode n'est pas appelée automatiquement lors du déclenchement de séquences par programme. Si vous devez effectuer la vérification, vous devez alors appeler shouldPerformSegueWithIdentifier pour déterminer s'il faut effectuer la transition.
if ([self shouldPerformSegueWithIdentifier:@"segueIdentifier" sender:nil]) { [self performSegueWithIdentifier:@"segueIdentifier" sender:nil]; }
Remarque: la réponse acceptée est la meilleure approche si vous pouvez cibler iOS 6. Pour cibler iOS 5, cette réponse fera l'affaire.
Je ne pense pas qu'il soit possible d'annuler un enchaînement prepareForSegue
. Je suggérerais de déplacer votre logique au point que le performSegue
message est d'abord envoyé.
Si vous utilisez Interface Builder pour câbler un enchaînement directement à un contrôle (par exemple, en liant un enchaînement directement à a UIButton
), vous pouvez accomplir cela avec un peu de refactoring. Câblez la séquence au contrôleur de vue au lieu d'un contrôle spécifique (supprimez l'ancien lien de séquence, puis faites glisser le contrôle du contrôleur de vue lui-même vers le contrôleur de vue de destination). Créez ensuite un IBAction
contrôleur dans votre vue et connectez le contrôle à IBAction. Ensuite, vous pouvez faire votre logique (vérifier TextField vide) dans l'IBAction que vous venez de créer, et y décider de le faire ou non par performSegueWithIdentifier
programmation.
Swift 3 : func shouldPerformSegue (withIdentifier identifier: String, sender: Any?) -> Bool
Valeur de retour true si la séquence doit être effectuée ou false si elle doit être ignorée.
Exemple :
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
}
Alternativement, c'est un comportement quelque peu mauvais d'offrir un bouton sur lequel un utilisateur ne devrait pas appuyer. Vous pouvez laisser la séquence câblée en position debout, mais commencez avec le bouton désactivé. Câblez ensuite le "editChanged" de l'UITextField à un événement sur le contrôle de vue ala
- (IBAction)nameChanged:(id)sender {
UITextField *text = (UITextField*)sender;
[nextButton setEnabled:(text.text.length != 0)];
}
Son facile dans le vif.
override func shouldPerformSegueWithIdentifier(identifier: String,sender: AnyObject?) -> Bool {
return true
}
Comme Abraham l'a dit, cochez valide ou non dans la fonction suivante.
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(nullable id)sender
{
// Check this identifier is OK or NOT.
}
Et, l' performSegueWithIdentifier:sender:
appel par programmation peut être bloqué par écrasement de la méthode suivante. Par défaut, il ne vérifie pas sa validité ou non -shouldPerformSegueWithIdentifier:sender:
, nous pouvons le faire manuellement.
- (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];
vraiment vraie?
performSegueWithIdentifier:sender:
méthode et n'appelez pas sa super
méthode.
Devrait effectuer Segue pour l'ouverture de session
-(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);
}
Semblable à la réponse de Kaolin est de laisser la seque câblée au contrôle mais de valider le contrôle en fonction des conditions dans la vue. Si vous tirez sur l'interaction de cellules de tableau, vous devez également définir la propriété userInteractionEnabled ainsi que désactiver les éléments dans la cellule.
Par exemple, j'ai un formulaire dans une vue de table groupée. L'une des cellules mène à une autre tableView qui agit comme sélecteur. Chaque fois qu'un contrôle est modifié dans la vue principale, j'appelle cette méthode
-(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 Réponse:
Voici la mise en œuvre de Swift 4 pour annuler la séquence:
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'autre façon consiste à remplacer la méthode de tableView avec willSelectRowAt et à retourner nil si vous ne souhaitez pas afficher la séquence.
showDetails()
- est un peu booléen. Dans la plupart des cas, doit être implémenté dans le modèle de données représenté dans la cellule avec indexPath
.
func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
if showDetails() {
return indexPath
}
return nil
}