一、 參考資料:
1.王巍 《博客》(非常詳細,推薦閱讀)
https://onevcat.com/2013/10/vc-transition-in-ios7/
2.xiao333ma 《博客》
http://blog.csdn.net/xiao333ma/article/details/49028241#t1
二、protocol
1.@protocol UIViewControllerContextTransitioning
- 這個接口用來提供切換上下文給開發者使用,包含了從哪個VC到哪個VC等各類信息,一般不需要開發者自己實現。具體來說,iOS7的自定義切換目的之一就是切換相關代碼解耦,在進行VC切換時,做切換效果實現的時候必須要需要切換前後VC的一些信息。
- 重要的方法:
1.-(UIView *)containerView;
-(UIView *)containerView;
VC切換所發生的view容器,開發者應該將切出的view移除,將切入的view加入到該view容器中。
2.-(UIViewController )viewControllerForKey:(NSString )key;
-(UIViewController *)viewControllerForKey:(NSString *)key;
提供一個key,返回對應的VC。現在的SDK中key的選擇只有:
UITransitionContextFromViewControllerKey表示將要切出VC。
UITransitionContextToViewControllerKey表示將要切入的VC。
3.-(CGRect)initialFrameForViewController:(UIViewController *)vc;
-(CGRect)initialFrameForViewController:(UIViewController *)vc;
某個VC的初始位置,可以用來做動畫的計算。
-(CGRect)finalFrameForViewController:(UIViewController *)vc;
與上面的方法對應,得到切換結束時某個VC應在的frame。
4.-(void)completeTransition:(BOOL)didComplete;
-(void)completeTransition:(BOOL)didComplete;
向這個context報告切換已經完成。
2.@protocol UIViewControllerAnimatedTransitioning
- 這個接口負責切換的具體內容,也即“切換中應該發生什麼”。開發者在做自定義切換效果時大部分代碼會是用來實現這個接口。
- 重要的方法:
1.-(NSTimeInterval)transitionDuration:(id < UIViewControllerContextTransitioning >)transitionContext;
-(NSTimeInterval)transitionDuration:(id < UIViewControllerContextTransitioning >)transitionContext;
系統給出一個切換上下文,我們根據上下文環境返回這個切換所需要的花費時間
(一般就返回動畫的時間就好了,SDK會用這個時間來在百分比驅動的切換中進行幀的計算)
2.-(void)animateTransition:(id < UIViewControllerContextTransitioning >)transitionContext;
-(void)animateTransition:(id < UIViewControllerContextTransitioning >)transitionContext;
在進行切換的時候將調用該方法,我們對於切換時的UIView的設置和動畫都在這個方法中完成。
3.@protocol UIViewControllerTransitioningDelegate
- 這個接口的作用比較簡單單一,在需要VC切換的時候系統會像實現了這個接口的對象詢問是否需要使用自定義的切換效果。
- 這個接口共有四個類似的方法:
前兩個方法是針對動畫切換的,我們需要分別在呈現VC和解散VC時,給出一個實現了UIViewControllerAnimatedTransitioning接口的對象(其中包含切換時長和如何切換)。後兩個方法涉及交互式切換
-(id< UIViewControllerAnimatedTransitioning >)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source;
-(id< UIViewControllerAnimatedTransitioning >)animationControllerForDismissedController:(UIViewController *)dismissed;
-(id< UIViewControllerInteractiveTransitioning >)interactionControllerForPresentation:(id < UIViewControllerAnimatedTransitioning >)animator;
-(id< UIViewControllerInteractiveTransitioning >)interactionControllerForDismissal:(id < UIViewControllerAnimatedTransitioning >)animator;
三、沒有交互的代碼具體思想步驟
注意,轉場動畫不難,但是套路一定要明顯,我們都是有原則的人。
* 情景: VC_a跳到VC_b
1.創建VC_a
並且在init方法裏面設置代理和modalPresentationStyle
- (instancetype)init
{
self = [super init];
if (self) {
self.transitioningDelegate = self;
self.modalPresentationStyle = UIModalPresentationCustom;
}
return self;
}
2.VC_a 遵守協議UIViewControllerTransitioningDelegate
- 這時候要實現協議的四個方法:
方法都返回了一個遵守UIViewControllerAnimatedTransitioning的id類型的動畫類
-(id< UIViewControllerAnimatedTransitioning >)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source;
-(id< UIViewControllerAnimatedTransitioning >)animationControllerForDismissedController:(UIViewController *)dismissed;
-(id< UIViewControllerInteractiveTransitioning >)interactionControllerForPresentation:(id < UIViewControllerAnimatedTransitioning >)animator;
-(id< UIViewControllerInteractiveTransitioning >)interactionControllerForDismissal:(id < UIViewControllerAnimatedTransitioning >)animator;
3.創建 AnimationTool (一個繼承自NSObject的動畫類)
並且AnimationTool遵守UIViewControllerAnimatedTransitioning協議
4.這是後我們可以從AnimationTool的協議方法實現對應的轉場方法(一般都用UIView的類動畫方法或者用layer動畫)
1.返回時長的方法
//返回的是動畫時長
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext{
return 0.5;
}
2.//具體動畫的實施的方法
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext{
//這裏面分爲modal和dismiss 兩種情況
}
四、有交互代碼實現思路 —— 手勢驅動的百分比切換
1. 創建一個UIPercentDrivenInteractiveTransition 類
1.這是一個實現了UIViewControllerInteractiveTransitioning接口的類,爲我們預先實現和提供了一系列便利的方法,可以用一個百分比來控制交互式切換的過程。一般來說我們更多地會使用某些手勢來完成交互式的轉移。
- 本類中重要的方法
-(void)updateInteractiveTransition:(CGFloat)percentComplete;
//更新百分比,一般通過手勢識別的長度之類的來計算一個值,然後進行更新。
-(void)cancelInteractiveTransition ;
//報告交互取消,返回切換前的狀態
–(void)finishInteractiveTransition;
//報告交互完成,更新到切換後的狀態
- 給view添加手勢(對於手勢的總結請看 iOS 手勢的基本介紹)