在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
這種場景在調用
[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
複製代碼
這種場景在
[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);
複製代碼
在默認狀況下,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);
複製代碼
- (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];
}
*/
}
}
複製代碼
- (void)startInteractiveTransition:(id<UIViewControllerContextTransitioning>)transitionContext{
//在這裏作些初始化的操做
[super startInteractiveTransition:transitionContext];
}
複製代碼
注意: (1) 在獲取
UIViewControllerAnimatedTransitioning
的代理方法中,若是有返回實現UIViewControllerAnimatedTransitioning
協議 的對象, 那麼就使用customer transition; 若是返回nil, 就使用系統默認的效果。 (2) 在獲取UIViewControllerInteractiveTransitioning
的代理方法中, 若是返回實現UIViewControllerInteractiveTransitioning
協議的對象, 那麼transition過程就是經過手勢控制的; 如過返回nil,就直接轉換。
將手勢識別器添加到合適的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.