Je suis sur le point de créer une application en utilisant un UINavigationController
pour présenter les prochains contrôleurs de vue. Avec iOS5, il existe une nouvelle méthode pour présenter UIViewControllers
:
presentViewController:animated:completion:
Maintenant, je me demande pourquoi n'y a-t-il pas de gestionnaire de complétion pour UINavigationController
? Il y a juste
pushViewController:animated:
Est-il possible de créer mon propre gestionnaire de complétion comme le nouveau presentViewController:animated:completion:
?
viewDidAppear:animated:
vous permet d'exécuter du code à chaque fois que votre contrôleur de vue apparaît à l'écran (viewDidLoad
seulement la première fois que votre contrôleur de vue est chargé)-(void)viewDidAppear:(BOOL)animated
Réponses:
Voir la réponse de par pour une autre solution plus à jour
UINavigationController
les animations sont exécutées avecCoreAnimation
, il serait donc logique d'encapsuler le code à l'intérieurCATransaction
et ainsi de définir un bloc de complétion.Swift :
Pour swift, je suggère de créer une extension en tant que telle
Usage:
Objectif c
Entête:
La mise en oeuvre:
la source
pushViewController:animated:
oupopViewController:animated
, les appelsviewDidLoad
etviewDidAppear
se produisent dans les cycles de boucle d'exécution suivants. J'ai donc l'impression que même si ces méthodes invoquent des animations, elles ne feront pas partie de la transaction fournie dans l'exemple de code. Était-ce votre souci? Parce que cette solution est fabuleusement simple.didShowViewController
. Bien que cette solution soit incroyablement simple, je remettrais en question sa "pérennité". Surtout compte tenu des changements pour afficher les rappels de cycle de vie fournis avec ios7 / 8iOS 7+ Swift
Swift 4:
EDIT: J'ai ajouté une version Swift 3 de ma réponse originale. Dans cette version, j'ai supprimé l'exemple de co-animation montré dans la version Swift 2 car il semble avoir dérouté beaucoup de gens.
Swift 3:
Swift 2:
la source
nil
en tant que bloc d'animation.nil
est une chose parfaitement valable à faire aussi.transitionCoordinator
est nul?transitionCoordinator
il est probable que vous appeliez cette fonction trop tôt dans le cycle de vie du contrôleur de navigation. Attendez au moins jusqu'à ce queviewWillAppear()
soit appelé avant d'essayer de pousser un contrôleur de vue avec une animation.Basé sur la réponse de par (qui était la seule qui fonctionnait avec iOS9), mais plus simple et avec un autre manquant (ce qui aurait pu conduire à ce que l'achèvement ne soit jamais appelé):
la source
Actuellement, le
UINavigationController
ne prend pas en charge cela. Mais il y a leUINavigationControllerDelegate
que vous pouvez utiliser.Un moyen simple d'y parvenir est de sous
UINavigationController
- classer et d'ajouter une propriété de bloc de complétion:Avant de pousser le nouveau contrôleur de vue, vous devez définir le bloc de complétion:
Cette nouvelle sous-classe peut être attribuée dans Interface Builder ou être utilisée par programme comme ceci:
la source
pushViewController:animated:completion:
ferait une solution élégante.Voici la version Swift 4 avec le Pop.
Juste au cas où quelqu'un d'autre en aurait besoin.
la source
Pour développer la réponse de @Klaas (et à la suite de cette question), j'ai ajouté des blocs de complétion directement à la méthode push:
A utiliser comme suit:
la source
if... (self.pushedVC == viewController) {
est incorrect. Vous devez tester l'égalité entre les objets en utilisantisEqual:
, par exemple,[self.pushedVC isEqual:viewController]
isEqual
serait probablement plus techniquement correct au cas où ils l'auraient jamais fait.Depuis iOS 7.0, vous pouvez utiliser
UIViewControllerTransitionCoordinator
pour ajouter un bloc d'achèvement push:la source
Swift 2.0
la source
Il faut un peu plus de travail pour ajouter ce comportement et conserver la possibilité de définir un délégué externe.
Voici une implémentation documentée qui maintient la fonctionnalité de délégué:
LBXCompletingNavigationController
la source