Les NavigationControllers ont des piles ViewController à gérer et des transitions d'animation limitées.
L'ajout d'un contrôleur de vue en tant que sous-vue à un contrôleur de vue existant nécessite de transmettre des événements au contrôleur de sous-vue, ce qui est difficile à gérer, chargé de petits désagréments et en général ressemble à un mauvais hack lors de la mise en œuvre (Apple recommande également de ne pas Ce faisant).
La présentation d'un contrôleur de vue modale place à nouveau un contrôleur de vue au-dessus d'un autre, et bien qu'il n'ait pas les problèmes de passage d'événement décrits ci-dessus, il n'échange pas vraiment le contrôleur de vue, il l'empile.
Les storyboards sont limités à iOS 5 et sont presque idéaux, mais ne peuvent pas être utilisés dans tous les projets.
Quelqu'un peut-il présenter un EXEMPLE DE CODE SOLIDE sur un moyen de changer les contrôleurs de vue sans les limitations ci-dessus et permet des transitions animées entre eux?
Un exemple proche, mais pas d'animation: Comment utiliser plusieurs contrôleurs de vue personnalisés iOS sans contrôleur de navigation
Modifier: l'utilisation du contrôleur de navigation est correcte, mais il doit y avoir des styles de transition animés (pas simplement les effets de diapositive), le contrôleur de vue affiché doit être complètement permuté (pas empilé). Si le deuxième contrôleur de vue doit supprimer un autre contrôleur de vue de la pile, il n'est pas suffisamment encapsulé.
Edit 2: iOS 4 devrait être le système d'exploitation de base pour cette question, j'aurais dû clarifier cela en mentionnant les storyboards (ci-dessus).
la source
Réponses:
EDIT: Nouvelle réponse qui fonctionne dans n'importe quelle orientation. La réponse d'origine ne fonctionne que lorsque l'interface est en orientation portrait. Il s'agit d'animations de transition de vue b / c qui remplacent une vue avec une vue différente doivent se produire avec des vues au moins un niveau en dessous de la première vue ajoutée à la fenêtre (par exemple
window.rootViewController.view.anotherView
).J'ai implémenté une classe de conteneur simple que j'ai appelée
TransitionController
. Vous pouvez le trouver sur https://gist.github.com/1394947 .En passant, je préfère l'implémentation dans une classe distincte b / c c'est plus facile à réutiliser. Si vous ne le souhaitez pas, vous pouvez simplement implémenter la même logique directement dans votre délégué d'application, éliminant ainsi le besoin de la
TransitionController
classe. La logique dont vous auriez besoin serait cependant la même.Utilisez-le comme suit:
Dans votre délégué d'application
Pour passer à un nouveau contrôleur de vue à partir de n'importe quel contrôleur de vue
EDIT: Réponse originale ci-dessous - ne fonctionne que pour l'orientation du portrait
J'ai fait les hypothèses suivantes pour cet exemple:
Vous avez un contrôleur de vue affecté en tant que
rootViewController
de votre fenêtreLorsque vous basculez vers une nouvelle vue, vous souhaitez remplacer le viewController actuel par le viewController propriétaire de la nouvelle vue. A tout moment, seul le viewController actuel est actif (par exemple alloué).
Le code peut être facilement modifié pour fonctionner différemment, le point clé est la transition animée et le contrôleur de vue unique. Assurez-vous de ne conserver aucun contrôleur de vue en dehors de son attribution
window.rootViewController
.Code pour animer la transition dans le délégué d'application
Exemple d'utilisation dans un contrôleur de vue
la source
TransitionController.m
surUIView *view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
, mais je ne l'ai utilisé que sur la toute dernière version d'iOS, alors testez attentivement.Vous pouvez utiliser le nouveau système de confinement viewController d'Apple. Pour plus d'informations, regardez la vidéo de la session WWDC 2011 "Implémentation du
UIViewController
confinement".Nouveau dans iOS5,
UIViewController
Containment vous permet d'avoir un viewController parent et un certain nombre de viewControllers enfants qui y sont contenus. C'est ainsi que fonctionne UISplitViewController. En faisant cela, vous pouvez empiler des contrôleurs de vue dans un parent, mais pour votre application particulière, vous utilisez simplement le parent pour gérer la transition d'un viewController visible à un autre. C'est la façon approuvée par Apple de faire les choses et d'animer à partir d'une vue enfant. Le contrôleur est indolore. De plus, vous pouvez utiliser toutes les différentesUIViewAnimationOption
transitions!De plus, avec UIViewContainment, vous n'avez pas à vous soucier, sauf si vous le souhaitez, du désordre de la gestion des viewControllers enfants pendant les événements d'orientation. Vous pouvez simplement utiliser ce qui suit pour vous assurer que votre parentViewController transmet les événements de rotation aux viewControllers enfants.
Vous pouvez faire ce qui suit ou similaire dans la méthode viewDidLoad de vos parents pour configurer le premier childViewController:
puis, lorsque vous avez besoin de changer le viewController enfant, vous appelez quelque chose du type suivant dans le viewController parent:
J'ai publié un exemple de projet complet ici: https://github.com/toolmanGitHub/stackedViewControllers . Cet autre projet montre comment utiliser
UIViewController
Containment sur certains types d'entrée viewController qui ne prennent pas tout l'écran. Bonne chancela source
[self.currentViewController willMoveToParentViewController:nil];
avant la transition?OK, je sais que la question dit sans utiliser de contrôleur de navigation, mais aucune raison de ne pas le faire. OP n'a pas répondu aux commentaires à temps pour que je m'endorme. Ne me rejetez pas. :)
Voici comment faire apparaître le contrôleur de vue actuel et basculer vers un nouveau contrôleur de vue à l'aide d'un contrôleur de navigation:
la source
Puisque je viens de rencontrer ce problème exact et que j'ai essayé des variantes de toutes les réponses préexistantes à un succès limité, je posterai comment je l'ai finalement résolu:
Comme décrit dans cet article sur les segues personnalisées , il est en fait très facile de créer des segues personnalisées. Ils sont également très faciles à connecter dans Interface Builder, ils gardent les relations dans IB visibles et ils ne nécessitent pas beaucoup de support de la part des contrôleurs de vue source / destination de la segue.
Le post lié ci-dessus fournit un code iOS 4 pour remplacer le contrôleur de vue de dessus actuel sur la pile navigationController par un nouveau à l'aide d'une animation de diapositive de haut.
Dans mon cas, je voulais qu'un remplacement similaire se produise, mais avec une
FlipFromLeft
transition. Je n'avais également besoin de support que pour iOS 5+. Code:Depuis RAFlipReplaceSegue.h:
De RAFlipReplaceSegue.m:
Maintenant, contrôlez tout en faisant glisser pour configurer tout autre type de segue, puis faites-en un segue personnalisé et saisissez le nom de la classe de segue personnalisée, et voilà!
la source
–performSegueWithIdentifier:sender:
méthode UIViewController .J'ai lutté avec celui-ci pendant longtemps, et l'un de mes problèmes est répertorié ici , je ne sais pas si vous avez eu ce problème. Mais voici ce que je recommanderais s'il doit fonctionner avec iOS 4.
Tout d'abord, créez une nouvelle
NavigationController
classe. C'est là que nous ferons tout le sale boulot - les autres classes pourront appeler "proprement" des méthodes d'instance commepushViewController:
et autres. Dans votre.h
:Le tableau de contrôleurs de vue enfant servira de magasin pour tous les contrôleurs de vue de notre pile. Nous transférerions automatiquement tout le code de rotation et de redimensionnement de la
NavigationController
vue de vers lecurrentController
.Maintenant, dans notre implémentation:
Vous pouvez maintenant implémenter votre propre coutume
pushViewController:
,popViewController
et autres, en utilisant ces appels de méthode.Bonne chance et j'espère que cela vous aidera!
la source
viewWillAppear
,viewDidAppear
etc.Essayez ce code.
Ce code donne la transition d'un contrôleur de vue vers un autre contrôleur de vue ayant un contrôleur de navigation.
la source