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.

相關文章
相關標籤/搜索