Lors du rejet d'un contrôleur de vue modale à l'aide de dismissViewController
, il est possible de fournir un bloc de saisie semi-automatique. Existe-t-il un équivalent similaire pour popViewController
?
L'argument de l'achèvement est assez pratique. Par exemple, je peux l'utiliser pour suspendre la suppression d'une ligne d'une vue de table jusqu'à ce que le modal soit hors écran, permettant à l'utilisateur de voir l'animation de ligne. En revenant d'un contrôleur de vue poussé, j'aimerais avoir la même opportunité.
J'ai essayé de placer popViewController
dans un UIView
bloc d'animation, où j'ai accès à un bloc de complétion. Cependant, cela produit des effets secondaires indésirables sur la vue sur laquelle on passe.
Si aucune méthode de ce type n'est disponible, quelles sont les solutions de contournement?
la source
Réponses:
Je sais qu'une réponse a été acceptée il y a plus de deux ans, mais cette réponse est incomplète.
Ceci est techniquement correct car l'
UINavigationController
API n'offre aucune option pour cela. Cependant, en utilisant le framework CoreAnimation, il est possible d'ajouter un bloc de complétion à l'animation sous-jacente:Le bloc de complétion sera appelé dès que l'animation utilisée par
popViewControllerAnimated:
se termine. Cette fonctionnalité est disponible depuis iOS 4.la source
extension UINavigationController { func popViewControllerWithHandler(handler: ()->()) { CATransaction.begin() CATransaction.setCompletionBlock(handler) self.popViewControllerAnimated(true) CATransaction.commit() } }
Pour la version iOS9 SWIFT - fonctionne comme un charme (n'avait pas été testé pour les versions antérieures). Basé sur cette réponse
la source
J'ai fait une
Swift
version avec des extensions avec la réponse @JorisKluivers .Cela appellera une fermeture d'achèvement une fois l'animation terminée pour
push
etpop
.la source
popViewController
oupushViewController
, mais si vous vérifiez ce qu'est le topViewController juste après, vous remarquerez qu'il s'agit toujours de l'ancien, commepop
oupush
ne s'est jamais produit ...SWIFT 4.1
la source
J'ai eu le même problème. Et parce que j'ai dû l'utiliser à plusieurs reprises, et dans des chaînes de blocs d'achèvement, j'ai créé cette solution générique dans une sous-classe UINavigationController:
En supposant
et
et
la source
Il n'y a aucun moyen de faire ce que vous voulez tout de suite. c'est-à-dire qu'il n'y a pas de méthode avec un bloc de complétion pour faire sauter un contrôleur de vue à partir d'une pile de navigation.
Ce que je ferais, c'est mettre la logique dans
viewDidAppear
. Cela sera appelé lorsque la vue aura fini de s'afficher à l'écran. Il sera appelé pour tous les différents scénarios d'apparition du contrôleur de vue, mais cela devrait être bien.Ou vous pouvez utiliser la
UINavigationControllerDelegate
méthodenavigationController:didShowViewController:animated:
pour faire une chose similaire. Ceci est appelé lorsque le contrôleur de navigation a fini de pousser ou de faire sauter un contrôleur de vue.la source
dismissViewController
. Peut-être que cela arriverapopViewController
. Déposer un radar :-).-dismissViewController:animated:completionBlock:
, vous pouvez obtenir l'animation via le délégué du contrôleur de navigation. Une fois l'animation terminée,-navigationController:didShowViewController:animated:
le délégué sera appelé et vous pourrez faire tout ce dont vous avez besoin sur place.Travailler correctement avec ou sans animation, et comprend également
popToRootViewController
:la source
completion()
async?completion
n'est jamais exécutée sur la même boucle d'exécution. cela garantit decompletion
ne jamais fonctionner sur la même boucle d'exécution lorsqu'il n'est pas animé. il vaut mieux ne pas avoir ce genre d'incohérence.Basé sur la réponse de @ HotJard, quand tout ce que vous voulez, c'est juste quelques lignes de code. Rapide et facile.
Swift 4 :
la source
Pour 2018 ...
si vous avez ça ...
et vous souhaitez ajouter une complétion ...
c'est si simple.
Astuce pratique ...
C'est la même chose pour le pratique
popToViewController
appel .Une chose typique est que vous avez une pile d'intégration d'un million d'écrans. Une fois terminé, vous revenez à votre écran "de base", puis lancez enfin l'application.
Donc, dans l’écran "de base", pour aller "tout en arrière",
popToViewController(self
la source
Le bloc de complétion est appelé après que la méthode viewDidDisappear a été appelée sur le contrôleur de vue présenté, donc mettre du code dans la méthode viewDidDisappear du contrôleur de vue popped devrait fonctionner de la même manière qu'un bloc de complétion.
la source
Réponse Swift 3, grâce à cette réponse: https://stackoverflow.com/a/28232570/3412567
la source
Version Swift 4 avec paramètre optionnel viewController pour accéder à un paramètre spécifique.
la source
Nettoyé la version Swift 4 en fonction de cette réponse .
la source
Il existe un pod appelé UINavigationControllerWithCompletionBlock qui ajoute la prise en charge d'un bloc d'achèvement lors de la poussée et de l'affichage d'un UINavigationController.
la source
2020 Swift 5.1 voie
Cette solution garantit que l'achèvement est exécuté une fois que popViewController est complètement terminé. Vous pouvez le tester en effectuant une autre opération sur le NavigationController à la fin: Dans toutes les autres solutions ci-dessus, UINavigationController est toujours occupé avec l'opération popViewController et ne répond pas.
la source
Pour être complet, j'ai préparé une catégorie Objective-C prête à l'emploi:
la source
J'ai réalisé exactement cela avec précision en utilisant un bloc. Je voulais que mon contrôleur de résultats récupéré affiche la ligne qui a été ajoutée par la vue modale, seulement une fois qu'elle a complètement quitté l'écran, afin que l'utilisateur puisse voir le changement en cours. En préparation pour segue qui est chargé d'afficher le contrôleur de vue modale, j'ai défini le bloc que je souhaite exécuter lorsque le modal disparaît. Et dans le contrôleur de vue modale, je remplace viewDidDissapear puis j'appelle le bloc. Je commence simplement les mises à jour lorsque le modal va apparaître et met fin aux mises à jour lorsqu'il disparaît, mais c'est parce que j'utilise un NSFetchedResultsController, mais vous pouvez faire ce que vous voulez à l'intérieur du bloc.
la source
Utilisez l'extension suivante sur votre code: (Swift 4)
la source