VCTransitionsLibrary 提供了許多適用于入棧,出棧,模態等場景下控制器切換時的轉場動畫.它本身提供了一個定義好的轉場動畫庫,你可以拖到自己工程中直接使用;也提供了許多擁有不同轉場動畫效果”互動控制器”,你可以直接使用這些控制器來和自定義動畫效果配合使用;而不是自己控制去控制交互.
項目主頁: VCTransitionsLibrary
最新示例: 點擊下載
注意: 自定義視圖控制器的轉場動畫為iOS7 + 通過 UIViewControllerTransitioningDelegate協議, UINavigationControllerDelegate協議和 UITabBarControllerDelegate 協議提供的系統級別的支持.這個庫的意義在于定義了常用的動畫效果,并封裝了常用的交互操作,簡化了iOS交互式轉場動畫的編碼量!
pod "VCTransitionsLibrary"
把文件 AnimationControllers
和 InteractionControllers 文件夾下所有代碼復制
到工程中即可.
在自定義轉場動畫時,有兩類關鍵的類:
注意: 動畫和交互是完全獨立的,這意味著你可以在其他任何自定義控制器上獨立使用交互控制器-很酷!
AnimationControllers 文件夾中提供了許多可以整合進你的工程中的動畫控制器:
UIViewControllerTransitioningDelegate 協議被用來在模態控制器顯示/隱藏時提供一個動畫控制器.當一個視圖控制器被模態顯示或隱藏時,它的transitioningDelegate屬性用來提供UIViewControllerTransitioningDelegate協議的支持.擔當代理角色的類,通過 animationControllerForPResentedController: presentingController: sourceController: 方法返回模態顯示時的動畫, 通過 animationControllerForDismissedController: 返回模態消失時的動畫即可.
UINavigationController 有一個
id<UINavigationControllerDelegate> delegate 屬性.只需要讓它的代理通過 navigationController: animationControllerForOperation: fromViewController: toViewController: 返回某個動畫效果即可.
為了同時設置出棧/入棧都合適的動畫效果(或者說,出棧/入棧時能使用相反方向的動畫),你可以參考下面代碼:
- (id<UIViewControllerAnimatedTransitioning>)navigationController: (UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC { // 出棧時,要反轉動畫方向. _animationController.reverse = operation == UINavigationControllerOperationPop; return _animationController;}
UITabBarController 有一個 id<UITabBarControllerDelegate> delegate屬性,只需要讓它的代理通過tabBarController: animationControllerForTransitionFromViewController: toViewController:返回某個動畫效果即可.
為了給動畫一個合適的方向,你可以比較兩個視圖控制器的索引:
- (id <UIViewControllerAnimatedTransitioning>)tabBarController:(UITabBarController *)tabBarController animationControllerForTransitionFromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC { NSUInteger fromVCIndex = [tabBarController.viewControllers indexOfObject:fromVC]; NSUInteger toVCIndex = [tabBarController.viewControllers indexOfObject:toVC]; _animationController.reverse = fromVCIndex < toVCIndex; return _animationController;}
交互控制器和動畫控制器配合使用,可以實現交互式的動畫轉場效果,比如可以讓用戶通過手勢來控制頁面間的導航.交互控制器允許用戶在一個轉場動畫中前進,后退,甚至退出.
交互控制器負責給視圖添加手勢,并負責在用戶使用某個手勢時進行相應地導航操作.
UIViewControllerTransitioningDelegate 協議,也用來提供對交互式轉場的支持.下面是一個結合清掃手勢和翻頁動畫的例子:
//實例變量,通常在你的初始化方法初始化它們CEFlipAnimationController *_animationController;CESwipeInteractionController *_interactionController;- (id<UIViewControllerAnimatedTransitioning>) animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source { // 允許交互控制器綁定它的手勢識別器. [_interactionController wireToViewController:presented forOperation:CEInteractionOperationDismiss]; _animationController.reverse = NO; return _animationController;}- (id<UIViewControllerAnimatedTransitioning>) animationControllerForDismissedController:(UIViewController *)dismissed { _animationController.reverse = YES; return _animationController;}- (id<UIViewControllerInteractiveTransitioning>) interactionControllerForDismissal: (id<UIViewControllerAnimatedTransitioning>)animator { // 如果有交互控制器被觸發了,就直接使用它.返回nil,是為了支持用戶通過點擊某個按鈕直接返回;此時不會觸發交互控制器. return _interactionController.interactionInProgress ? _interactionController : nil;}
UINavigationControllerDelegate 也有方法為交互式轉場提供支持.一個典型的類似于上上面代碼的模式:
// 實例變量,通常在你的初始化方法中初始化它們.CEFlipAnimationController *_animationController;CESwipeInteractionController *_interactionController;- (id<UIViewControllerAnimatedTransitioning>) navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC { // 把交互控制器綁定到你的視圖控制器上. [_interactionController wireToViewController:toVC forOperation:CEInteractionOperationPop]; _animationController.reverse = operation == UINavigationControllerOperationPop; return _animationController;}- (id <UIViewControllerInteractiveTransitioning>) navigationController:(UINavigationController *)navigationController interactionControllerForAnimationController:(id <UIViewControllerAnimatedTransitioning>)animationController { //如果有交互控制器被觸發了,就直接使用它.返回nil,是為了支持用戶通過點擊某個按鈕直接返回;此時不會觸發交互控制器. return _interactionController.interactionInProgress ? _interactionController : nil;}
UITabBarControllerDelegate 協議也為交互式轉場提供了支持.但是由于代理方法在首次初始化時不被執行,所有需要其他方式來綁定交互控制器,如KVO:
@implementation TabBarViewController { CEFoldAnimationController *_animationController; CESwipeInteractionController *_swipeInteractionController;}- (id)initWithCoder:(NSCoder *)aDecoder { if (self = [super initWithCoder:aDecoder]) { self.delegate = self; // 創建交互/動畫控制器. _swipeInteractionController = [CESwipeInteractionController new]; _animationController = [CEFoldAnimationController new]; _animationController.folds = 3; // 使用觀察者模式監測被選中的選擇器的變化情況. [self addObserver:self forKeyPath:@"selectedViewController" options:NSKeyValueObservingOptionNew context:nil]; } return self;}- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{ if ([keyPath isEqualToString:@"selectedViewController"] ) { // 把交互控制器綁定到視圖控制器上. [_swipeInteractionController wireToViewController:self.selectedViewController forOperation:CEInteractionOperationTab]; }}- (id <UIViewControllerAnimatedTransitioning>)tabBarController:(UITabBarController *)tabBarController animationControllerForTransitionFromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC { NSUInteger fromVCIndex = [tabBarController.viewControllers indexOfObject:fromVC]; NSUInteger toVCIndex = [tabBarController.viewControllers indexOfObject:toVC]; _animationController.reverse = fromVCIndex < toVCIndex; return _animationController;}-(id<UIViewControllerInteractiveTransitioning>)tabBarController:(UITabBarController *)tabBarController interactionControllerForAnimationController:(id<UIViewControllerAnimatedTransitioning>)animationController{ return _swipeInteractionController.interactionInProgress ? _swipeInteractionController : nil;}@end
新聞熱點
疑難解答