iOS自定义转场动画
2014-11-26 14:08
190 查看
在iOS程序里出现得最多的转场动画,就是UINavigationController的Push和Pop了,看多了就觉得有些无聊了,还好苹果提供了自定义转场动画的API,往下看。
首页,要明白既然转场动画是通过导航控制器来完成(UIViewController模态除外),那么就往UINavigationController看,既然是转场,那么在两个控制器切换的中间,就是转场动画发生的地方,一提到“将要出现”,“已经出现”,“将要消失”,“已经消失”,条件反射就想到了UINavigationController的代理方法:
注意最后两个方法,就是它了,注意可用的iOS版本:NS_AVAILABLE_IOS(7_0)
id <UIViewControllerAnimatedTransitioning>,一个遵循UIViewControllerAnimatedTransitioning的对象,点开它:
说了这么多理论,总结一下自定义转场动画大致的设置思路:
1、自定义一个继承自NSObject并且遵从UIViewControllerAnimatedTransitioning协议的类,里面实现协议方法,设置好动画时长和具体内容;
2、在转场动画发生的viewcontroller里,遵从UINavigationControllerDelegate协议,实现协议方法
示例:
新建一个有两个viewcontroller的工程:FirstViewController、SecondViewcontroller,将FirstViewcontroller加到一个导航控制器里,它的view上有一个“push”按钮,点它可以将SecondViewController push进来,SecondViewController上有一个“pop”按钮,点它可以pop到FirstViewController,描述得已经很清楚了吧。
创建两个继承自NSObject的类,一个叫PushAnimation,一个叫PopAnimation,它们都遵循UIViewControllerAnimatedTransitioning协议:
在PushAnimation.h
在PopAnimation里实现下面方法(push的逆动画,其实可以只创建一个类,通过“顺”or“逆”来判断执行的动画):
在FirstViewController.m里添加下面代码:
同样,在SecondViewController里设置pop的动画代码,即可,更好的方法,可以写一个继承自UINavigationController的子类,统一实现协议方法。
首页,要明白既然转场动画是通过导航控制器来完成(UIViewController模态除外),那么就往UINavigationController看,既然是转场,那么在两个控制器切换的中间,就是转场动画发生的地方,一提到“将要出现”,“已经出现”,“将要消失”,“已经消失”,条件反射就想到了UINavigationController的代理方法:
@protocol UINavigationControllerDelegate <NSObject> @optional // Called when the navigation controller shows a new top view controller via a push, pop or setting of the view controller stack. - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated; - (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated; - (NSUInteger)navigationControllerSupportedInterfaceOrientations:(UINavigationController *)navigationController NS_AVAILABLE_IOS(7_0); - (UIInterfaceOrientation)navigationControllerPreferredInterfaceOrientationForPresentation:(UINavigationController *)navigationController NS_AVAILABLE_IOS(7_0); - (id <UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController interactionControllerForAnimationController:(id <UIViewControllerAnimatedTransitioning>) animationController NS_AVAILABLE_IOS(7_0); - (id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC NS_AVAILABLE_IOS(7_0); @end
注意最后两个方法,就是它了,注意可用的iOS版本:NS_AVAILABLE_IOS(7_0)
- (id <UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController interactionControllerForAnimationController:(id <UIViewControllerAnimatedTransitioning>) animationController NS_AVAILABLE_IOS(7_0);这个方法是讲的手势百分比交互,今天不谈,说最后一个方法,它的返回值是
id <UIViewControllerAnimatedTransitioning>,一个遵循UIViewControllerAnimatedTransitioning的对象,点开它:
@protocol UIViewControllerAnimatedTransitioning <NSObject> // This is used for percent driven interactive transitions, as well as for container controllers that have companion animations that might need to // synchronize with the main animation. - (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext; // This method can only be a nop if the transition is interactive and not a percentDriven interactive transition. - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext; @optional两个方法,第一个是返回动画持续时间,第二个是动画具体内容。
说了这么多理论,总结一下自定义转场动画大致的设置思路:
1、自定义一个继承自NSObject并且遵从UIViewControllerAnimatedTransitioning协议的类,里面实现协议方法,设置好动画时长和具体内容;
2、在转场动画发生的viewcontroller里,遵从UINavigationControllerDelegate协议,实现协议方法
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC在该方法里返回自定义的动画类的一个对象即可。
示例:
新建一个有两个viewcontroller的工程:FirstViewController、SecondViewcontroller,将FirstViewcontroller加到一个导航控制器里,它的view上有一个“push”按钮,点它可以将SecondViewController push进来,SecondViewController上有一个“pop”按钮,点它可以pop到FirstViewController,描述得已经很清楚了吧。
创建两个继承自NSObject的类,一个叫PushAnimation,一个叫PopAnimation,它们都遵循UIViewControllerAnimatedTransitioning协议:
@interface PushAnimation : NSObject<UIViewControllerAnimatedTransitioning> @end @interface PopAnimation : NSObject<UIViewControllerAnimatedTransitioning> @end
在PushAnimation.h
//返回动画持续时间 - (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext { return 2.0f; } - (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext { //获取起点controller UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; //获取终点controller UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; //获取转场容器视图 UIView *containerView = [transitionContext containerView]; //设置终点视图的frame CGRect frame = [transitionContext initialFrameForViewController:fromVC]; CGRect offScreenFrame = frame; //先将其设置到屏幕外边,通过动画进入 offScreenFrame.origin.x = offScreenFrame.size.width; toVC.view.frame = offScreenFrame; //添加视图 [containerView addSubview:toVC.view]; //执行动画 [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{ //设置缩放和透明度 fromVC.view.transform = CGAffineTransformMakeScale(0.8, 0.8); fromVC.view.alpha = 0.5; //设置位置 toVC.view.frame = frame; } completion:^(BOOL finished) { fromVC.view.transform = CGAffineTransformIdentity; [transitionContext completeTransition:![transitionContext transitionWasCancelled]]; }]; }
在PopAnimation里实现下面方法(push的逆动画,其实可以只创建一个类,通过“顺”or“逆”来判断执行的动画):
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext { return 2.0f; } - (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext { UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; UIView *containerView = [transitionContext containerView]; toVC.view.transform = CGAffineTransformMakeScale(0.8, 0.8); toVC.view.alpha = 0.5; CGRect frame = [transitionContext initialFrameForViewController:fromVC]; CGRect offScreenFrame = frame; offScreenFrame.origin.x = offScreenFrame.size.width; [containerView insertSubview:toVC.view belowSubview:fromVC.view]; [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{ toVC.view.transform = CGAffineTransformIdentity; toVC.view.alpha = 1.0f; fromVC.view.frame = offScreenFrame; } completion:^(BOOL finished) { fromVC.view.transform = CGAffineTransformIdentity; [transitionContext completeTransition:![transitionContext transitionWasCancelled]]; }]; }
在FirstViewController.m里添加下面代码:
#import "PushAnimation.h" @interface FirstViewController ()<UINavigationControllerDelegate> { PushAnimation *_pushAni; } @end - (void)viewDidLoad { [super viewDidLoad]; _pushAni = [PushAnimation new]; } - (void)viewDidAppear:(BOOL)animated { self.navigationController.delegate = self; [super viewDidAppear:animated]; } - (void)viewDidDisappear:(BOOL)animated { if (self.navigationController.delegate == self) { self.navigationController.delegate = nil; } [super viewDidDisappear:animated]; } - (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC { if (operation == UINavigationControllerOperationPush) { return _pushAni; } return nil; }
同样,在SecondViewController里设置pop的动画代码,即可,更好的方法,可以写一个继承自UINavigationController的子类,统一实现协议方法。
相关文章推荐
- iOS 8自定义动画转场上手指南
- IOS图像8之IOS7.0之后UIViewController自定义转场动画
- iOS自定义转场动画实战讲解
- iOS自定义转场动画(下)
- 【Swift】IOS开发中自定义转场动画
- iOS开发>学无止境 - 自定义控制器转场动画及实现下拉菜单的小Demo
- iOS自定义转场动画实战讲解
- IOS实战之自定义转场动画详解
- iOS自定义转场动画实战讲解
- iOS自定义转场动画的实现
- iOS自定义转场动画(4)——自定义模态跳转之dismiss与手势驱动
- VCTransitionsLibrary –自定义iOS交互式转场动画的库
- iOS自定义转场动画<转>
- IOS图像5之UIView动画、自定义转场动画、delegate
- iOS自定义转场动画
- iOS自定义转场动画(1)——自定义Push转场动画
- iOS自定义转场动画(2)——自定义Pop转场动画并加入手势驱动
- iOS自定义转场详解03——实现通过圆圈放大缩小的转场动画
- iOS自定义转场动画(上)
- iOS自定义转场动画