J'ai une application basée sur la navigation et je veux changer l'animation des animations push et pop. Comment ferais-je ça?
Modifier 2018
Il y a eu beaucoup de réponses à cette question et cela fait un bon moment maintenant, j'ai re-choisi la réponse à ce que je pense être le plus pertinent maintenant. S'il y a quelqu'un qui pense le contraire, veuillez me le faire savoir dans les commentaires
Réponses:
Pour 2019, la "réponse finale!"
Préambule:
Disons que vous êtes nouveau dans le développement iOS. Confusément, Apple propose deux transitions qui peuvent être utilisées facilement. Ce sont: "crossfade" et "flip".
Mais bien sûr, "crossfade" et "flip" sont inutiles. Ils ne sont jamais utilisés. Personne ne sait pourquoi Apple a fourni ces deux transitions inutiles!
Alors:
Supposons que vous souhaitiez effectuer une transition ordinaire et courante, telle que "diapositive". Dans ce cas, vous devez faire une énorme quantité de travail! .
Ce travail est expliqué dans cet article.
Juste pour répéter:
Étonnamment: avec iOS, si vous voulez les transitions quotidiennes les plus simples et les plus courantes (comme une diapositive ordinaire), vous devez effectuer tout le travail de mise en œuvre d'une transition personnalisée complète .
Voici comment procéder ...
1. Vous avez besoin d'une coutume
UIViewControllerAnimatedTransitioning
Vous avez besoin d'un bool de votre choix
popStyle
. (Est-ce qu'il saute ou saute?)Vous devez inclure
transitionDuration
(trivial) et l'appel principal,animateTransition
En fait, vous devez écrire deux routines différentes pour l'intérieur
animateTransition
. Un pour le push et un pour la pop. Nommez-les probablementanimatePush
etanimatePop
. À l'intérieuranimateTransition
, branchez -vous simplement surpopStyle
les deux routinesL'exemple ci-dessous fait un simple déplacement / déplacement
Dans vos routines
animatePush
etanimatePop
. Vous devez obtenir le "de la vue" et le "voir". (Comment faire, est indiqué dans l'exemple de code.)et vous devez
addSubview
pour la nouvelle vue "à".et vous devez appeler
completeTransition
à la fin de votre animeAlors ..
Puis ...
2. Utilisez-le dans votre contrôleur de vue.
Remarque: étrangement, vous n'avez qu'à le faire dans le "premier" contrôleur de vue. (Celui qui est "en dessous".)
Avec celui que vous sautez dessus , ne faites rien . Facile.
Alors ta classe ...
devient...
C'est tout.
Poussez et éclatez exactement comme d'habitude, aucun changement. Pousser ...
et pour le faire apparaître, vous pouvez le faire si vous le souhaitez sur l'écran suivant:
Phew.
3. Profitez également des autres réponses de cette page qui expliquent comment remplacer AnimatedTransitioning
Faites défiler jusqu'à @AlanZeino et @elias answer pour plus de discussion sur la façon d'utiliser
AnimatedTransitioning
les applications iOS de nos jours!la source
animatePush
queanimatePop
sont et .. les deux directions différentes!J'ai fait ce qui suit et cela fonctionne bien .. et est simple et facile à comprendre ..
Et la même chose pour push ..
Version Swift 3.0:
la source
Animated:NO
pièce est vitale. SiYES
c'est réussi, les animations se mélangent et provoquent des effets amusants.setViewControllers:
C'est ainsi que j'ai toujours réussi à accomplir cette tâche.
Pour Push:
Pour la pop:
J'obtiens toujours beaucoup de commentaires à ce sujet, donc je vais aller de l'avant et le mettre à jour pour utiliser des blocs d'animation qui est de toute façon la méthode recommandée par Apple pour faire des animations.
Pour Push:
Pour la pop:
la source
super
parself.navigationController
UIViewController
sous-classe d'un nom sans partie "ViewController". Ce nom est plus approprié pour UIView.pour pousser
pour la pop
la source
@Magnus répond, alors seulement pour Swift (2.0)
Quelques notes:
Vous pouvez également le faire avec Segue, implémentez-le simplement dans
prepareForSegue
oushouldPerformSegueWithIdentifier
. Cependant , cela conservera également l'animation par défaut. Pour résoudre ce problème, vous devez vous rendre dans le storyboard, cliquez sur la séquence et décochez la case «Animations». Mais cela limitera votre application pour IOS 9.0 et supérieur (au moins quand je l'ai fait dans Xcode 7).Lors d'une séquence, les deux dernières lignes doivent être remplacées par:
Même si je mets false, cela l'ignore en quelque sorte.
la source
N'oubliez pas que dans Swift , l' extension est définitivement vos amis!
la source
L'utilisation d'appels privés est une mauvaise idée car Apple n'approuve plus les applications qui le font. Vous pourriez peut-être essayer ceci:
la source
-pushViewController:transition:forceImmediate:
ce qui serait une mauvaise idée.Étant donné que c'est le meilleur résultat sur Google, j'ai pensé partager ce que je pense être la manière la plus sensée; qui consiste à utiliser l'API de transition iOS 7+. J'ai implémenté cela pour iOS 10 avec Swift 3.
Il est assez simple de combiner cela avec la façon dont
UINavigationController
s'anime entre deux contrôleurs de vue si vous créez une sous-classe deUINavigationController
et renvoyez une instance d'une classe conforme auUIViewControllerAnimatedTransitioning
protocole.Par exemple, voici ma
UINavigationController
sous - classe:Vous pouvez voir que je mets le
UINavigationControllerDelegate
à lui-même, et dans une extension de ma sous-classe, j'implémente la méthodeUINavigationControllerDelegate
qui vous permet de retourner un contrôleur d'animation personnalisé (c'est-à-direNavigationControllerAnimation
). Ce contrôleur d'animation personnalisé remplacera l'animation stock pour vous.Vous vous demandez probablement pourquoi je passe l'opération à l'
NavigationControllerAnimation
instance via son initialiseur. Je le fais pour que dansNavigationControllerAnimation
la mise en œuvre duUIViewControllerAnimatedTransitioning
protocole, je sache quelle est l'opération (c'est-à-dire «pousser» ou «pop»). Cela permet de savoir quel type d'animation je dois faire. La plupart du temps, vous souhaitez effectuer une animation différente en fonction de l'opération.Le reste est assez standard. Implémentez les deux fonctions requises dans le
UIViewControllerAnimatedTransitioning
protocole et animez comme vous le souhaitez:Il est important de se rappeler que pour chaque type d'opération différent (c'est-à-dire «pousser» ou «pop»), les contrôleurs de vue vers et depuis seront différents. Lorsque vous êtes en mode push, le contrôleur to view sera celui qui est poussé. Lorsque vous êtes dans une opération de pop, le contrôleur de vue sera celui vers lequel la transition est effectuée et le contrôleur de vue sera celui qui sera sauté.
En outre, le
to
contrôleur de vue doit être ajouté en tant que sous-vue decontainerView
dans le contexte de transition.Une fois votre animation terminée, vous devez appeler
transitionContext.completeTransition(true)
. Si vous effectuez une transition interactive, vous devrez retourner dynamiquement unBool
àcompleteTransition(didComplete: Bool)
, selon que la transition est terminée à la fin de l'animation.Enfin ( lecture facultative ), vous voudrez peut-être voir comment j'ai effectué la transition sur laquelle je travaillais. Ce code est un peu plus hacky et je l'ai écrit assez rapidement donc je ne dirais pas que c'est un excellent code d'animation mais il montre toujours comment faire la partie animation.
La mienne était une transition vraiment simple; Je voulais imiter la même animation que UINavigationController, mais au lieu de l'animation `` page suivante en haut '', je voulais implémenter une animation 1: 1 de l'ancien contrôleur de vue en même temps que la nouvelle vue contrôleur apparaît. Cela a pour effet de donner l'impression que les deux contrôleurs de vue sont attachés l'un à l'autre.
Pour l'opération de poussée, cela nécessite d'abord de définir l'
toViewController
origine de la vue du sur l'écran hors axe x, de l'ajouter comme sous-vue ducontainerView
, de l'animer sur l'écran en la mettantorigin.x
à zéro. En même temps, j'anime lafromViewController
vue en laorigin.x
désactivant de l'écran:L'opération pop est essentiellement l'inverse. Ajoutez le en
toViewController
tant que sous-vue ducontainerView
, et animez lefromViewController
vers la droite pendant que vous l'animeztoViewController
depuis la gauche:Voici un aperçu de l'ensemble du fichier Swift:
https://gist.github.com/alanzeino/603293f9da5cd0b7f6b60dc20bc766be
la source
Il y a UINavigationControllerDelegate et UIViewControllerAnimatedTransitioning là-bas, vous pouvez changer l'animation pour tout ce que vous voulez.
Par exemple, il s'agit d'une animation pop verticale pour VC:
}
Puis
Tutoriel utile https://www.objc.io/issues/5-ios7/view-controller-transitions/
la source
Basé sur la réponse mise à jour pour swift 4
jordanperry
Pour pousser
UIViewController
Pour la pop
la source
Voici comment j'ai fait la même chose dans Swift:
Pour Push:
Pour la pop:
En fait, j'ai fait cela un peu différemment de certaines des réponses ci-dessus - mais comme je suis nouveau dans le développement Swift, ce n'est peut-être pas correct. J'ai remplacé
viewWillDisappear:animated:
et ajouté le code pop là-dedans:la source
@Luca Davanzo's answer in Swift 4.2
la source
J'essayais récemment de faire quelque chose de similaire. J'ai décidé que je n'aimais pas l'animation coulissante de UINavigationController, mais je ne voulais pas non plus faire les animations que UIView vous donne comme curl ou quelque chose comme ça. Je voulais faire un fondu enchaîné entre les vues lorsque je pousse ou que j'éclate.
Le problème là-bas implique le fait que la vue supprime littéralement la vue ou en saute une par-dessus la vue actuelle, donc un fondu ne fonctionne pas. La solution à laquelle j'ai abouti consistait à prendre ma nouvelle vue et à l'ajouter en tant que sous-vue à la vue de dessus actuelle de la pile UIViewController. Je l'ajoute avec un alpha de 0, puis fais un fondu enchaîné. Une fois la séquence d'animation terminée, je pousse la vue sur la pile sans l'animer. Je reviens ensuite à l'ancien topView et nettoie les choses que j'avais modifiées.
C'est un peu plus compliqué que cela, car vous avez les éléments de navigation que vous devez ajuster pour que la transition soit correcte. De plus, si vous effectuez une rotation, vous devez ensuite ajuster les tailles d'image lorsque vous ajoutez les vues en tant que sous-vues afin qu'elles s'affichent correctement à l'écran. Voici une partie du code que j'ai utilisé. J'ai sous-classé le UINavigationController et remplacé les méthodes push et pop.
Comme je le mentionne dans le code, j'ai toujours un élément de bouton de barre gauche, donc je ne vérifie pas s'il est nul avant de le placer dans le tableau que je passe comme contexte pour le délégué d'animation. Si vous faites cela, vous voudrez peut-être faire cette vérification.
Le problème que j'ai trouvé était que si vous plantiez du tout dans la méthode déléguée, cela ne planterait pas le programme. Cela empêche simplement le délégué de terminer, mais vous ne recevez aucun type d'avertissement.
Donc, comme je faisais mon nettoyage dans cette routine de délégué, cela provoquait un comportement visuel étrange car il ne terminait pas le nettoyage.
Le bouton précédent que je crée appelle une méthode "goBack", et cette méthode appelle simplement la routine pop.
Aussi, voici ma routine pop.
C'est à peu près ça. Vous aurez besoin d'un code supplémentaire si vous souhaitez implémenter des rotations. Vous devrez définir la taille du cadre de vos vues que vous ajoutez en tant que sous-vues avant de les afficher, sinon vous rencontrerez des problèmes d'orientation est paysage, mais la dernière fois que vous avez vu la vue précédente, c'était portrait. Donc, vous l'ajoutez en tant que sous-vue et l'ajoutez en fondu, mais il apparaît en tant que portrait, puis lorsque nous sautons sans animation, la même vue, mais celle qui est dans la pile, est maintenant paysage. Le tout semble un peu génial. L'implémentation de rotation de chacun est un peu différente, donc je n'ai pas inclus mon code ici.
J'espère que cela aide certaines personnes. J'ai cherché partout quelque chose comme ça et je n'ai rien trouvé. Je ne pense pas que ce soit la réponse parfaite, mais cela fonctionne vraiment bien pour moi à ce stade.
la source
Vous pouvez maintenant utiliser
UIView.transition
. Notez celaanimated:false
. Cela fonctionne avec toute option de transition, pop, push ou remplacement de pile.la source
En utilisant la réponse d'iJordan comme inspiration, pourquoi ne pas simplement créer une catégorie sur UINavigationController à utiliser dans toute votre application au lieu de copier / coller ce code d'animation partout?
UINavigationController + Animation.h
UINavigationController + Animation.m
Importez ensuite simplement le fichier UINavigationController + Animation.h et appelez-le normalement:
la source
C'est très simple
la source
Jetez un œil à ADTransitionController , une alternative au remplacement de UINavigationController avec des animations de transition personnalisées (son API correspond à l'API de UINavigationController) que nous avons créé chez Applidium.
Vous pouvez utiliser différentes animations prédéfinies pour des actions push et pop telles que Swipe , Fade , Cube , Carrousel , Zoom , etc.
la source
Bien que toutes les réponses ici soient excellentes et la plupart fonctionnent très bien, il existe une méthode légèrement plus simple qui produit le même effet ...
Pour Push:
Pour la pop:
la source
Je ne connais aucun moyen de modifier publiquement l'animation de transition.
Si le bouton « retour » est pas nécessaire que vous devriez utiliser les contrôleurs de vue modales d'avoir la « poussée de bas » / « flip » / « fade » / (≥3.2) transitions « curl page ».
Du côté privé , la méthode
-pushViewController:animated:
appelle la méthode non documentée-pushViewController:transition:forceImmediate:
, donc par exemple si vous voulez une transition de gauche à droite, vous pouvez utiliserCependant, vous ne pouvez pas modifier la transition "pop" de cette façon.
la source
Voir ma réponse à cette question pour un moyen de le faire en beaucoup moins de lignes de code. Cette méthode vous permet d'animer une pseudo- "Push" d'un nouveau contrôleur de vue comme vous le souhaitez, et lorsque l'animation est terminée, elle configure le contrôleur de navigation comme si vous aviez utilisé la méthode Push standard. Mon exemple vous permet d'animer un slide-in de gauche ou de droite. Code répété ici pour plus de commodité:
la source
À partir de l'exemple d'application, découvrez cette variation. https://github.com/mpospese/MPFoldTransition/
la source
Utilisez simplement:
la source
Le réaliser est une vieille question. Je voudrais toujours poster cette réponse, car j'ai eu quelques problèmes pour en créer plusieurs
viewControllers
avec les réponses proposées. Ma solution est de sousUINavigationController
-classer et de remplacer toutes les méthodes pop et push.FlippingNavigationController.h
FlippingNavigationController.m:
la source
Je sais que ce fil est vieux, mais je pensais que je mettrais mes deux cents. Vous n'avez pas besoin de faire une animation personnalisée, il y a une façon simple (peut-être hacky) de le faire. Au lieu d'utiliser push, créez un nouveau contrôleur de navigation, faites du nouveau contrôleur de vue le contrôleur de vue racine de ce contrôleur de navigation, puis présentez le contrôleur de navigation à partir du contrôleur de navigation d'origine. Le cadeau est facilement personnalisable avec de nombreux styles, et pas besoin de faire une animation personnalisée.
Par exemple:
Et vous pouvez changer le style de présentation comme vous le souhaitez.
la source
J'ai trouvé un moyen légèrement récursif de le faire qui fonctionne pour mes besoins. J'ai une variable d'instance BOOL que j'utilise pour bloquer l'animation popping normale et remplacer mon propre message pop non animé. La variable est initialement définie sur NO. Lorsque vous appuyez sur le bouton Précédent, la méthode déléguée le définit sur OUI et envoie un nouveau message pop non animé à la barre de navigation, appelant ainsi à nouveau la même méthode déléguée, cette fois avec la variable définie sur OUI. Lorsque la variable est définie sur YES, la méthode déléguée la définit sur NO et renvoie YES pour permettre à la pop non animée de se produire. Après le retour du deuxième appel de délégué, nous nous retrouvons dans le premier, où NO est renvoyé, bloquant la pop animée d'origine! Ce n'est pas aussi désordonné que ça en a l'air. Ma méthode shouldPopItem ressemble à ceci:
Travaille pour moi.
la source