Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
495 views
in Technique[技术] by (71.8m points)

ios4 - iPhone: How to switch tabs with an animation?

I'm switching tabs programmatically in a tab bar driven application using UITabBarController.selectedIndex. The problem I'm trying to solve is how to animate the transition between the views. ie. from the view of the current tab to the view of the selected tab.

The first thought was to make use of the UITabBarControllerDelegate, but it appears that this is not called when programmatically switching tabs. I'm now considering the UITabBarDelegate.didSelectItem: as a possible hook to set a transition animation.

Has anyone managed to animate the transitions? If yes, how ?

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Update 04/2016: Justed wanted to update this to say thank you to everyone for all the votes. Please also note that this was originally written way back when ... before ARC, before constraints, before ... a lot of stuff! So please take this into account when deciding whether to use these techniques. There may be more modern approaches. Oh, and if you find one. Please add a response so everyone can see. Thanks.

Some time later ...

After much research I came up with two working solutions. Both of these worked and did the animation between tabs.

Solution 1: transition from view (simple)

This is the easiest and makes use of a predefined UIView transition method. With this solution we don't need to manage the views because the method does the work for us.

// 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: scroll (more complex)

A more complex solution, but gives you more control of the animation. In this example we get the views to slide on and off. With this one we need to manage the views ourselves.

// 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;                
                     }
                 }];

This Solution in Swift:

extension TabViewController: UITabBarControllerDelegate {
      public func tabBarController(tabBarController: UITabBarController, shouldSelectViewController viewController: UIViewController) -> Bool {

           let fromView: UIView = tabBarController.selectedViewController!.view
           let toView  : UIView = viewController.view
           if fromView == toView {
                 return false
           }

           UIView.transitionFromView(fromView, toView: toView, duration: 0.3, options: UIViewAnimationOptions.TransitionCrossDissolve) { (finished:Bool) in

        }
        return true
   }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...