126 votes

Démission d'un contrôleur de vue présenté

J'ai une question théorique. Je suis en train de lire l'article d'Apple ViewController guide.

Ils ont écrit :

Lorsqu'il s'agit de licencier un contrôleur de vue présenté, la fonction l'approche préférée est de laisser le contrôleur de vue présentateur le congédier le renvoyer. En d'autres termes, dans la mesure du possible, le contrôleur de vue qui a présenté le contrôleur de vue doit également prendre la responsabilité de l'exécution de la tâche. qui a présenté le contrôleur de vues doit également prendre la responsabilité de l'écarter. Bien qu'il existe plusieurs techniques pour notifier au contrôleur de vue qui le présente que le contrôleur de vue qu'il a présenté présenté, la technique préférée est la délégation.

Mais je ne peux pas expliquer, pourquoi je dois créer un protocole dans le VC présenté et ajouter une variable de délégué, créer une méthode de délégué dans le VC présenté pour renvoyer le VC présenté, au lieu d'un simple appel dans a présenté méthode du contrôleur de vue

[self dismissViewControllerAnimated:NO completion:nil] ?

Pourquoi le premier choix est-il meilleur ? Pourquoi Apple le recommande-t-elle ?

135voto

foundry Points 15423

Je pense qu'Apple couvre un peu ses arrières ici pour une pièce potentiellement maladroite de l'API.

  [self dismissViewControllerAnimated:NO completion:nil]

C'est en fait un peu un violon. Bien que vous puissiez - légitimement - l'appeler sur le contrôleur de vue présenté, tout ce qu'il fait est de transmettre le message au contrôleur de vue présenté. Si vous voulez faire quelque chose de plus que simplement rejeter le VC, vous devez le savoir, et vous devez le traiter de la même manière qu'une méthode déléguée - car c'est à peu près ce qu'il est, une méthode déléguée intégrée et quelque peu inflexible.

Il se peut qu'ils aient rencontré beaucoup de mauvais code de la part de personnes ne comprenant pas vraiment comment cela se passe, d'où leur prudence.

Mais bien sûr, si tout ce que vous devez faire est de rejeter la chose, allez-y.

Ma propre approche est un compromis, au moins elle me rappelle ce qui se passe :

  [[self presentingViewController] dismissViewControllerAnimated:NO completion:nil]

[Swift]

  self.presentingViewController?.dismiss(animated: false, completion:nil)

61voto

Suragch Points 197

Mise à jour pour Swift 3

Je suis venu ici juste pour rejeter le View Controller actuel (présenté). Je fais cette réponse pour tous ceux qui viennent ici dans le même but.

Contrôleur de navigation

Si vous utilisez un contrôleur de navigation, c'est assez facile.

Retournez au contrôleur de vue précédent :

// Swift
self.navigationController?.popViewController(animated: true)

// Objective-C
[self.navigationController popViewControllerAnimated:YES];

Retournez au contrôleur de vue racine :

// Swift
self.navigationController?.popToRootViewController(animated: true)

// Objective-C
[self.navigationController popToRootViewControllerAnimated:YES];

(Merci à cette réponse pour l'Objective-C).

Contrôleur de vue modale

Lorsqu'un contrôleur de vue est présenté de manière modale, vous pouvez le congédier (à partir du deuxième contrôleur de vue) en appelant

// Swift
self.dismiss(animated: true, completion: nil)

// Objective-C
[self dismissViewControllerAnimated:YES completion:nil];

El documentation dit,

Le contrôleur de présentation est responsable de la suppression de la vue. qu'il a présenté. Si vous appelez cette méthode sur le contrôleur de vue présenté présenté lui-même, UIKit demande au contrôleur de vue qui le présente de gérer le renvoi.

Le contrôleur de vue présenté peut donc l'appeler sur lui-même. Ici est un exemple complet.

Délégués

La question de l'OP portait sur la complexité de l'utilisation des délégués pour rejeter une vue.

Jusqu'à présent, je n'ai pas eu besoin d'utiliser les délégués puisque j'ai généralement un contrôleur de navigation ou des contrôleurs de vue modaux, mais si je dois utiliser le modèle de délégué à l'avenir, j'ajouterai une mise à jour.

56voto

Michael Enriquez Points 1166

Cela permet de réutiliser le contrôleur de vue.

Votre contrôleur d'affichage ne devrait pas se soucier du fait qu'il soit présenté comme une modale, poussé sur un contrôleur de navigation ou autre. Si votre contrôleur d'affichage se désactive lui-même, alors vous supposez qu'il est présenté de manière modale. Vous ne serez pas en mesure de pousser ce contrôleur de vue sur un contrôleur de navigation.

En mettant en œuvre un protocole, vous laissez le contrôleur de vue parent décider de la manière dont il doit être présenté/poussé et rejeté/supprimé.

7voto

Essayez ceci :

[self dismissViewControllerAnimated:true completion:nil];

6voto

jhilgert00 Points 2617

D'après mon expérience, cela s'avère pratique lorsque vous devez le renvoyer de tout ViewController que vous voulez et exécutez des tâches différentes pour chaque viewcontroller qui le rejette. Tout viewController qui adopte le protocole peut renvoyer la vue de sa propre manière. (ipad vs iphone, ou passer des données différentes lors du renvoi depuis des vues différentes, appeler des méthodes différentes lors du renvoi, etc )

Edit :

Donc, pour clarifier, si tout ce que vous voulez faire est de rejeter la vue, je ne vois pas la nécessité de configurer le protocole de délégué. Si vous avez besoin de faire des choses différentes après vous le renvoyez à partir de différents contrôleurs de vue de présentation, il serait votre meilleure façon d'aller en utilisant le délégué.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X