Animation push sans storyboard
Bonjour,
je connais bien la programmation osx, mais je débute encore en ios.
J'ai un controller mainVC qui a une propriété mainView.
J'ai deux controllers firstVC et secondVC.
mainView a pour fonction d'afficher le contenu de firstVC ou de secondVC.
Je n'utilise ni les storyboards ni les childViewControllers. Pour l'instant, tout marche mais je n'arrive pas à animer le passage firstVC -> secondVC. Je souhaiterais avoir une animation de type push.
Voici ce que je fais:
CATransition *animation = [CATransition animation];
[animation setDuration:0.25];
[animation setType:kCATransitionPush];
[animation setSubtype:kCATransitionFromRight];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.25];
[self.mainView removeAllSubviews_cbd_] ;
[self.mainView fillWithSubview_cbd_:self.secondVC.view] ;
[UIView commitAnimations];
(code copié-collé du web)
ça ne marche pas.
J'ai aussi essayé (code que j'ai écrit)
[UIView animateWithDuration:1
delay:0
options:0
animations:^{
[self.mainView removeAllSubviews_cbd_] ;
[self.mainView fillWithSubview_cbd_:self.secondVC.view] ;
}
completion:nil] ;
ça ne donne aucune animation.
Si des programmeurs plus expérimentés pouvaient m'éclairer de leur lanterne, merci !
Colas
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Est-ce que ça ne convient pas à ton besoin ?
Merci Céroce !
Je suis plus dans le cas où les "sous-vues" sont toutes à un même niveau (cf. mon message avec le dessin de l'interface) que dans le cas où il y a un VC parent qui a des sous-vues, etc. Mais je ne doute pas que je puisse faire entrer mon cas d'utilisation dans celui prévu par Apple.
Je suis aussi preneur d'une solution qui expliquerait pourquoi l'animation bête et méchante ne marche pas. J'ai parcouru SO et certains messages expliquent qu'il faut mettre en cache la vue courante dans une image bitmat, etc.
Dans les méthodes +[UIView animate...], il faut changer dans le bloc des propriétés animables de UIView: frame, bounds, center, transform, alpha, backgroundColor ou contentStretch.
Faire un push consiste à déplacer la frame. Je ne sais pas trop ce que tu fais dans tes méthodes.
Ensuite, tu ne dois pas retirer la vue d'origine avant que l'autre soit affichée, il faut donc le faire dans le bloc de complétion.
Cela dit, il me semble qu'on peut tout à fait utiliser un navigation controller qui ne remplit pas tout l'écran (il hérite de UIViewController, après tout). En fait, je l'ai déjà fait. Donc, tu pourrais le disposer sur la droite, masquer sa barre de navigation. C'est une solution plus élégante et bien plus facile à programmer.
Je ne vois pas trop en lisant ton code ce que tu attends comme animation.
Tu sembles supprimer le firstVC et tu ajoutes le secondVC, façon removeFromSuperview: et addSubview:, directement.
En quoi cela, si tu l'animes, est sensé faire une animation de "push" de la droite vers la gauche ?
Si tu veux reproduire l'animation push du UINavigationController, il faut que tu ajoutes le secondViewController mais avec une frame à droite de l'écran, que tu animes ensuite le changement de la frame de sa position à droite de l'écran jusqu'à sa position finale (frame de l'écran), et qu'une fois l'animation finie tu supprimes le firstVC. Comme ça tu vas bien animer le déplacement de ton secondVC de la droite vers le centre, et ton firstVC sera bien encore visible pendant ton animation, et supprimé seulement à la fin.
Je confirme, cela consiste à utiliser un UINavigationController (avec la barre de navigation affichée ou masquée selon ce que tu veux) dans un Container View Controller.
Honnêtement colas2 tu dis ne pas utiliser les childViewController, mais je pense que c'est un tort, car ils collent justement parfaitement à ce genre de cas d'usage. D'ailleurs les UINavigationController, UITabBarController & co sont des Container View Controllers ayant des childViewControllers, donc si tu veux reproduire leur fonctionnement, c'est bête de ne pas profiter de cette API faite pour.
Merci de vos réponses.
Je vais essayer d'utiliser navigationController.
@Ali : je vais me renseigner sur les childViewControllers (je n'ai jamais regardé cette API, qui n'existe pas sous osx)
Tu as oublié de gérer les ViewControllers. Si tu insistes à éviter les moyens déjà fourni en Cocoa, il te faut t'informer sur le sujets des ViewControllers et leurs hiérarchies en plus de vues et ses sous-vues.
il vaut l'effort de regarder la vidéo 218 du WWDC 2013.
Sinon, utilises les storyboards et ce sera beaucoup plus facile
Creating Custom Container View Controllers (View Controller Programming Guide for iOS)
T'as tout d'expliqué là dedans, avec exemple, schémas et bout de code à l'appui.
Finalement, je crois que je ne vais pas utiliser les parent/child view controllers.
Je suis confronté au problème suivant : la méthode transitionFromViewController:toViewController:duration:options:animations:completion: ne permet pas d'ajouter des contraintes lors de l'ajout du nouveau child view controller (cf. SO)
C'est finalement ce que j'ai fait (cf. plus bas)
J'ai une question à propos de cette solution.
Imaginons que je souhaite faire un effet push entre deux vues, mais que ces deux vues ne vont pas occuper tout l'écran, mais seulement une partie :
• viewForTransition n'est pas tout l'écran, mais seulement un rectangle dans l'écran
• firstView et secondView remplissent alternativement viewForTransition, avec effet push entre les deux.
Avec la solution donnée par @Aligator, en imaginant que secondView va pusher firstView, on va voir secondView traverser tout l'écran, en venant de la gauche (par exemple), pour à la fin de mettre "dans" viewForTransition.
Ce n'est pas exactement l'effet que je souhaiterais. Je voudrais que le push ait lieu à l'intérieur de viewForTransition. Autrement dit, je voudrais qu'on voie secondView traverser viewForTransition, en venant de la gauche (par exemple), pour à la fin être entièrement dans viewForTransition.
Pour l'instant, je m'en suis sorti en mettant des views blanches opaques autour de viewForTransition, mais :
• il y a un petit écart temporel entre le moment où l'on clique pour avoir la transition et le moment entre secondView commence à traverser viewForTransition.
• cette solution est crade... et pas générique
Si vous avez lu jusque là ;-) et que vous avez des idées, je suis preneur.
Voilà mon code pour l'instant :
et
2) quand tu veux faire ton push, ajoute secondView en subview de viewTransitionContainer, anime tes frames, puis à la fin de l'anim supprime firstView
Si tu préfères utiliser la méthode de [UIView transitionFromView:toView:etc...] c'est exactement le même principe : le secret est de prévoir une vue parente (avec clipToBounds=YES) dans laquelle tu vas encapsuler tes firstView/secondView pour clipper l'animation.
Merci ! Je vais essayer ça.
ça marche.
Merci de votre aide et de vos retours !