108 votes

iPhone: Comment changer d'onglet avec une animation?

Je suis passer onglets par programmation dans un onglet de la barre d'application axée sur l'aide d' UITabBarController.selectedIndex. Le problème, je vais essayer de le résoudre est de savoir comment animer la transition entre les points de vue. c'est à dire. à partir de l'affichage de l'onglet en cours à la vue de l'onglet sélectionné.

La première pensée a été de faire usage de la UITabBarControllerDelegate, mais il semble que ce n'est pas appelé lorsque par programme de commutation onglets. Je suis maintenant en considérant l' UITabBarDelegate.didSelectItem: comme crochet pour définir une animation de transition.

Quelqu'un a réussi à animer les transitions? Si oui, comment ?

156voto

drekka Points 10020

Après beaucoup de recherches, j'ai trouvé deux solutions de travail. Ces deux travaillé et fait de l'animation entre les onglets.

Solution 1: la transition de la vue (simple)

C'est le plus facile et permet l'utilisation d'un prédéfini UIView méthode de transition. Avec cette solution, nous n'avez pas besoin de gérer les points de vue parce que la méthode fait le travail pour nous.

// Get views. controllerIndex is passed in as the controller we want to go to. 
UIView * fromView = tabBarController.selectedViewController.view;
UIView * toView = [[tabBarController.viewControllers objectAtIndex:controllerIndex] view];

// Transition using a page curl.
[UIView transitionFromView:fromView 
                    toView:toView 
                  duration:0.5 
                   options:(controllerIndex > tabBarController.selectedIndex ? UIViewAnimationOptionTransitionCurlUp : UIViewAnimationOptionTransitionCurlDown)
                completion:^(BOOL finished) {
                    if (finished) {
                        tabBarController.selectedIndex = controllerIndex;
                    }
                }];

Solution 2: faire défiler (plus complexe)

De plus en plus complexe de la solution, mais vous donne plus de contrôle de l'animation. Dans cet exemple, nous obtenons le point de vue de glisser sur et en dehors. Avec ce dont nous avons besoin pour gérer la vue de nous-mêmes.

// Get the views.
UIView * fromView = tabBarController.selectedViewController.view;
UIView * toView = [[tabBarController.viewControllers objectAtIndex:controllerIndex] view];

// Get the size of the view area.
CGRect viewSize = fromView.frame;
BOOL scrollRight = controllerIndex > tabBarController.selectedIndex;

// Add the to view to the tab bar view.
[fromView.superview addSubview:toView];

// Position it off screen.
toView.frame = CGRectMake((scrollRight ? 320 : -320), viewSize.origin.y, 320, viewSize.size.height);

[UIView animateWithDuration:0.3 
                 animations: ^{

                     // Animate the views on and off the screen. This will appear to slide.
                     fromView.frame =CGRectMake((scrollRight ? -320 : 320), viewSize.origin.y, 320, viewSize.size.height);
                     toView.frame =CGRectMake(0, viewSize.origin.y, 320, viewSize.size.height);
                 }

                 completion:^(BOOL finished) {
                     if (finished) {

                         // Remove the old view from the tabbar view.
                         [fromView removeFromSuperview];
                         tabBarController.selectedIndex = controllerIndex;                
                     }
                 }];

25voto

Ryan Wu Points 1081

Ce qui suit est mon tentative d’utiliser la forme de code drekka dans la méthode delegate (UITabBarControllerDelegate)

 - (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController {

    NSArray *tabViewControllers = tabBarController.viewControllers;
    UIView * fromView = tabBarController.selectedViewController.view;
    UIView * toView = viewController.view;
    if (fromView == toView)
        return;
    NSUInteger fromIndex = [tabViewControllers indexOfObject:tabBarController.selectedViewController];
    NSUInteger toIndex = [tabViewControllers indexOfObject:viewController];

    [UIView transitionFromView:fromView
                        toView:toView
                      duration:0.3
                       options: toIndex > fromIndex ? UIViewAnimationOptionTransitionFlipFromLeft : UIViewAnimationOptionTransitionFlipFromRight
                    completion:^(BOOL finished) {
                        if (finished) {
                            tabBarController.selectedIndex = toIndex;
                        }
                    }];
    return true;
}
 

15voto

flopr Points 128

Je pense que vous pouvez facilement réaliser des transitions pour UITabBarControlelr en utilisant CATransition; Cela résoudra également les effets secondaires de l’utilisation de transitionFromView: toView:

Utilisez-le dans votre classe TabBarController personnalisée étendue à partir de UITabBarController.

 - (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController (UIViewController*)viewController {

    CATransition *animation = [CATransition animation];
    [animation setType:kCATransitionFade];
    [animation setDuration:0.25];
    [animation setTimingFunction:[CAMediaTimingFunction functionWithName:
                              kCAMediaTimingFunctionEaseIn]];
    [self.view.window.layer addAnimation:animation forKey:@"fadeTransition"];
}
 

J'espère que cela t'aides :)

2voto

texian Points 160

un correctif pour l'animation nerveuse ...

UIView * fromView = self.view.superview;

2voto

eagle Points 58

cela peut être résolu de deux manières

1 - Ecrivez ceci une fois dans votre fichier AppDelegate.m. N'oubliez pas d'inclure UITabBarControllerDelegate en utilisant <> après le signe deux-points (:) dans votre AppDelegate.h

 -(void)tabBarController:(UITabBarController *)tabBarControllerThis didSelectViewController:(UIViewController *)viewController
{
    [UIView transitionWithView:viewController.view
                      duration:0.1
                       options:UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionTransitionCrossDissolve
                    animations:^(void){
                    } completion:^(BOOL finished){
                        [UIView beginAnimations:@"animation" context:nil];
                        [UIView setAnimationDuration:0.7];
                        [UIView setAnimationBeginsFromCurrentState:YES];
                        [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft
                                               forView:viewController.view
                                                 cache:NO];
                        [UIView commitAnimations];
                    }];
}
 

2 - Ecrivez ceci dans chacun de vos fichiers ViewController.m

 -(void)viewWillAppear:(BOOL)animated
{
    [UIView transitionWithView:self.view
                      duration:1.0
                       options:UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionTransitionCrossDissolve
                    animations:^(void){
                        [super viewWillAppear:YES];
                    } completion:^(BOOL finished){
                    }];
}
 

espérons que cette aide ...!

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X