iOS自定义 Transitions 动画总结

在iOS中,当导航控制器调用 [navigationController pushViewController:secondViewController animated:YES]时,系统会提供一个过渡的动画来提升用户体验。另外,一个控制器present(或者dismiss)另外一个控制器时([self presentViewController:secondViewController animated:YES completion:NULL])系统也会提供相应的过渡动画。为了使app交互效果更加精彩,iOS为咱们提供了在不一样场景下自定义过渡动画以及经过手势控制过渡进度的实现方案。效果先看这个demo效果html

自定义 Transitions 动画的效果由实现了UIViewControllerAnimatedTransitioning协议的实例定制; 手势控制过渡进度由实现了UIViewControllerInteractiveTransitioning协议的实例定制。在不一样的Transition场景下, 咱们经过不一样的代理方法向系统提供自定义的遵照UIViewControllerAnimatedTransitioning协议的对象和遵照UIViewControllerInteractiveTransitioning协议的对象。 知道如何将本身定义的UIViewControllerAnimatedTransitioning对象以及UIViewControllerInteractiveTransitioning对象提供会给系统;而且知道如何实现UIViewControllerInteractiveTransitioning协议以及实现UIViewControllerInteractiveTransitioning协议, 你就能够自如的实现本身的Transition动画了。ios


一,自定义Transitions动画使用场景

1, 一个控制器present另外一个控制器的自定义转换动画

这种场景在调用[self presentViewController:secondViewController animated:YES completion:NULL][self dismissViewControllerAnimated:YES completion:NULL];时产生。实现步骤以下:bash

(1) 对被present的控制器设置transitioning代理对象 secondViewController.transitioningDelegate = presentationController; presentationController是实现协议UIViewControllerTransitioningDelegate 的实例。 同时设置secondViewController . modalPresentationStyle = UIModalPresentationCustom;app

(2) 代理对象要实现UIViewControllerTransitioningDelegate 协议的方法,在代理方法中返回遵照UIViewControllerAnimatedTransitioning协议和UIViewControllerInteractiveTransitioning协议的对象。post

@protocol UIViewControllerTransitioningDelegate <NSObject>
@optional
//返回用于present的自定义transition动画。
- (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source;
//返回用于dismiss时的自定义transition动画。
- (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed;
//返回用于present时的可进行手势交互的transition动画。
- (nullable id <UIViewControllerInteractiveTransitioning>)interactionControllerForPresentation:(id <UIViewControllerAnimatedTransitioning>)animator;
//返回用于dismiss时的可进行手势交互的transition动画。 
- (nullable id <UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:(id <UIViewControllerAnimatedTransitioning>)animator;
//这个在自定义PresentationController时使用。下面的sample code有相应demo.
- (nullable UIPresentationController *)presentationControllerForPresentedViewController:(UIViewController *)presented presentingViewController:(UIViewController *)presenting sourceViewController:(UIViewController *)source NS_AVAILABLE_IOS(8_0);
@end
复制代码

2, UINavigationController 中控制器的transition

这种场景在[navigationController pushViewController:secondViewController animated:YES][self.navigationController popViewControllerAnimated:YES];下产生。实现步骤以下:动画

(1) 设置 导航控制器的delegate : self.navigationController.delegate = self;ui

(2) 实现代理方法, 在代理方法中返回实现UIViewControllerAnimatedTransitioning,和UIViewControllerInteractiveTransitioning(手势控制切换过程)协议的对象。spa

//返回可用于进行手势交互的transition动画。 
- (nullable id <UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController
                          interactionControllerForAnimationController:(id <UIViewControllerAnimatedTransitioning>) animationController NS_AVAILABLE_IOS(7_0);
//返回自定义过渡动画
- (nullable id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
                                   animationControllerForOperation:(UINavigationControllerOperation)operation
                                                fromViewController:(UIViewController *)fromVC
                                                  toViewController:(UIViewController *)toVC  NS_AVAILABLE_IOS(7_0);
复制代码

3, UITabBarController中切换控制器的transition

在默认状况下,UITabBarController切换控制器是没有过渡动画效果的。经过自定义Transitiond动画为切换控制器加上过渡效果。其实现步骤以下:代理

(1) 设置 UITabBarController实例的代理对象: self.tabBarController.delegate = self; 代理对象必须遵照UITabBarControllerDelegate协议。code

(2) 实现代理方法以下代理方法, 在代理方法中返回遵照相应协议的对象。

- (nullable id <UIViewControllerInteractiveTransitioning>)tabBarController:(UITabBarController *)tabBarController interactionControllerForAnimationController: (id <UIViewControllerAnimatedTransitioning>)animationController NS_AVAILABLE_IOS(7_0);
	
- (nullable id <UIViewControllerAnimatedTransitioning>)tabBarController:(UITabBarController *)tabBarController
	            animationControllerForTransitionFromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC  NS_AVAILABLE_IOS(7_0);
复制代码

二,实现协议UIViewControllerAnimatedTransitioning

- (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext{
	//返回执行转换控制器的时长
}

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext{
    /**
    (1), 从transitionContext 获取执行动画须要的信息例如
         UIView *containerView = transitionContext.containerView;
         UIView *fromView;
         UIView *toView;
    
    (2),将toView 添加到containerView  中(全部的要执行的动画都须要在这里面完成)
    (3),执行动画
     [UIView animateWithDuration:transitionDuration
                     animations:^{
                         //在这里执行一些动画
                     } completion:^(BOOL finished) {
                         //动画结束后,必定要调用
                         BOOL wasCancelled = [transitionContext transitionWasCancelled];
                         [transitionContext completeTransition:!wasCancelled];
     }
                         
     */
}
}
复制代码

三,实现协议 UIViewControllerInteractiveTransitioning

- (void)startInteractiveTransition:(id<UIViewControllerContextTransitioning>)transitionContext{
	//在这里作些初始化的操做    
    [super startInteractiveTransition:transitionContext];
}
复制代码

注意: (1) 在获取UIViewControllerAnimatedTransitioning的代理方法中,若是有返回实现UIViewControllerAnimatedTransitioning协议 的对象, 那么就使用customer transition; 若是返回nil, 就使用系统默认的效果。 (2) 在获取 UIViewControllerInteractiveTransitioning的代理方法中, 若是返回实现UIViewControllerInteractiveTransitioning协议的对象, 那么transition过程就是经过手势控制的; 如过返回nil,就直接转换。


四, 使用手势控制Transition 的大体流程

将手势识别器添加到合适的view上, 根据监听到的手势的状态作出相应操做

switch (gestureRecognizer.state)
    {
        case UIGestureRecognizerStateBegan:
            /**
             监听到手势开始,触发transition。 也就是调用下面的某个方法
             [self.navigationController pushViewController:secondViewController animated:YES];(导航控制器中, 或者pop)
             或者[self presentViewController:secondViewController animated:YES completion:NULL];(presentViewController, 或者dismiss)
             或者[tabBarController setSelectedIndex:2];(tabBarController )
             */
           
            break;
        case UIGestureRecognizerStateChanged:
            /**
             更新进度
             */
            [self updateInteractiveTransition:[self percentForGesture:gestureRecognizer]];
            break;
        case UIGestureRecognizerStateEnded:
            // Dragging has finished.
            // Complete or cancel, depending on how far we've dragged. //根据进度决定是finishInteractiveTransition 仍是 cancelInteractiveTransition 。 if ([self percentForGesture:gestureRecognizer] >= 0.5f) [self finishInteractiveTransition]; else [self cancelInteractiveTransition]; break; default: // Something happened. cancel the transition. [self cancelInteractiveTransition]; break; } 复制代码

五,Sample Code

具体代码与理论相结合每每事半功倍。推荐给你们一些比较好的Sample Code.

相关文章
相关标签/搜索