web-dev-qa-db-fra.com

prepareForSegue n'est pas appelé lorsque je clique sur un bouton sans utiliser performSegueWithIdentifier

Sur la base du cours iOS de Stanford, je joue avec des contrôleurs de vue modale. Dans la démo, ils ont un bouton qui lancerait une vue modale et quand il est cliqué, la fonction prepareForSegue est appelée. J'ai imité le code et l'implémentation dans mon projet à la seule différence que ma démo est sur un storyboard iPhone et la leur sur iPad.

J'ai remarqué que pendant que mon contrôleur de vue modale arrive, il n'appelle pas prepareForSegue avant cela. J'ai recherché le projet de Stanford pour voir où ils peuvent enregistrer tout comportement de transition avant que prepareForSegue soit appelé mais il n'y a aucune preuve. Quelqu'un peut-il nous éclairer à ce sujet? J'ai recherché le débordement de pile et tout ce que j'ai trouvé, c'est que les utilisateurs manquaient l'implémentation d'appel de performSegueWithIdentifier. Cependant, dans la démo de Stanford, ils ne font jamais ça.

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier hasPrefix:@"Create Label"]) {
        AskerViewController *asker = (AskerViewController *)segue.destinationViewController;
        asker.question = @"What do you want your label to say?";
        asker.answer = @"Label Text";
        asker.delegate = self;
    }

}

Voici un exemple de ce storyboard: enter image description here

Voici un exemple de mon storyboard: enter image description here

Dans le débogueur, lorsque j'arrête dans le code de démonstration de Stanford, la pile d'appels montre que le storyboard exécute une action de transition, que dois-je configurer dans mon storyboard pour obtenir le même résultat? enter image description here

26
Amro Younes

Eh bien, il s'avère que mon contrôleur de vue où le bouton appelle la vue modale n'avait pas la bonne classe où prepareForSegue est implémenté. C'était l'UIViewController par défaut au lieu de ma classe personnalisée.

La façon dont je l'ai compris était de mettre un point d'arrêt dans viewDidLoad et même cela ne cassait pas et donc je soupçonnais que dans le storyboard je n'avais pas la bonne classe associée à la vue où le bouton est implémenté.

31
Amro Younes

Pour les autres personnes ayant ce problème, si vous utilisez maintenant Swift 3 ayant la fonction suivante ne générera pas d'erreurs car c'est la syntaxe correcte mais cela ne fonctionnera pas car c'est le Swift 2:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    // code
}

Vous devez mettre à jour la fonction Swift 3 "préparer" pour que cela fonctionne pour les séquences:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    // code
}
11
Manuel BM

Lorsque vous connectez une séquence automatique pour une vue de table, il y a, en plus de la réponse d'Amro (sans affecter votre sous-classe correspondante), deux autres cas où prepareForSegue peut ne pas être appelé. Assurez-vous d'avoir:

  1. branché la séquence à partir de la cellule prototype de vue de table, pas le contrôleur de vue de table.

  2. utilisé une séquence dans le groupe "Sélection séquence" dans le menu local de connexion de séquence, pas une sous "Action accessoire".

Hooking up automatic segues

[Cliquez sur l'image pour agrandir]

10
DonVaughn

Que ce soit un code Modal ou Push Segue ci-dessous sera toujours appelé

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"Create Label"]) {
        SignUpViewController *asker = segue.destinationViewController;
    }
}
5
bhavya kothari

Dans mon cas, cela s'est produit parce que mon contrôleur étendait un autre contrôleur (Eureka Form View Controller = FormViewController) qui a implémenté la fonction performSegue comme ceci:

open override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    // code
}

Ma fonction a été implémentée comme ceci:

func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    // code
}

Pour résoudre ce problème, j'ai simplement ajouté un remplacement avant:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    // code
}

Voila!

2
Vincent Guyard

J'ai eu un problème similaire.

Le processus de réflexion a été:

  1. assurez-vous d'avoir la bonne signature de méthode. Il a changé en Swift 3.
  2. Assurez-vous ensuite que la façon dont vous avez accroché le bouton (ou tout ce qui déclenche la séquence) correspond à la façon dont vous avez accroché la séquence dans le storyboard. Parfois, vous appelez un bouton, mais vous n'avez pas correctement raccordé la séquence de ce bouton au Viewcontroller de destination.
  3. Assurez-vous que l'identifiant de la séquence est correct. Bien que ce ne soit pas la raison pour laquelle prepareForSegue n'est pas appelé, c'est uniquement la raison pour laquelle une séquence spécifique n'est pas appelée.
1
Honey

J'ai eu un problème similaire avec UICollectionViewCell comme source de segue.
Il semble que pour que la séquence de storyboard fonctionne (sans performSegueWithIdentifier), vous devez disposer d'une sous-classe personnalisée de UICollectionViewCell, et l'utiliser comme Class pour le CollectionViewCell sur le story-board.

1
Mohit Joshi

Dans mon cas, je n'ai pas placé le module sous le nom de la classe dans le storyboard du contrôleur de vue qui contient la séquence. Il a été défini sur aucun et une fois que j'ai cliqué dans le champ du module, il a été défini sur le projet/module correct et a résolu le problème.

1
Logan Sease

Dans mon cas, j'ai une classe de base pour plusieurs contrôleurs de vue dans mon projet. Cette classe de base a une implémentation de prepareForSegue() qui n'était pas appelée dans tous les cas. Le problème était que dans l'un de mes contrôleurs de vue qui hérite de la classe de base et remplace son implémentation prepareForSegue(), j'ai oublié d'appeler super.prepareForSegue().

0
ClayJ