自定義動(dòng)畫切換的相關(guān)主要API
在學(xué)習(xí)自定義轉(zhuǎn)場(chǎng)動(dòng)畫之前魂毁,我們一起來(lái)看看相關(guān)SDK以及它們的關(guān)系和典型用法玛迄。這幾個(gè)接口和類的名字都比較類似婚苹,但是還是能比較好的描述出各自的職能中符,一開(kāi)始可能比較容易迷惑配阵,但是當(dāng)我們自己手動(dòng)實(shí)現(xiàn)一兩個(gè)例子過(guò)后冗澈,它們之間的關(guān)系就比較明了钦勘。
@protocol UIViewControllerContextTransitioning
這個(gè)接口用來(lái)提供切換上下文給開(kāi)發(fā)者使用,包含了從哪個(gè)VC到哪個(gè)VC等各類信息亚亲,一般不需要開(kāi)發(fā)中自己實(shí)現(xiàn)彻采。具體來(lái)說(shuō),iOS7的自定義切換目的之一就是切換相關(guān)代碼解藕捌归,在進(jìn)行VC切換時(shí)肛响,做切換效果實(shí)現(xiàn)的時(shí)候需要切換前后VC的一些信息,系統(tǒng)在新加入的API的比較的地方都會(huì)提供一個(gè)實(shí)現(xiàn)了該接口的對(duì)象以供我們使用惜索。
對(duì)于切換的動(dòng)畫實(shí)現(xiàn)來(lái)說(shuō)特笋,這個(gè)接口種最重要的方法有:
1. -(UIView *)containerView; VC切換所發(fā)生的view容器,開(kāi)發(fā)者應(yīng)該將切出的view移除巾兆,將切入的view加入到該view容器中猎物。
2. -(UIViewController *)viewControllerForKey:(NSString *)key; 提供一個(gè)key,返回對(duì)應(yīng)的VC〗撬埽現(xiàn)在的SDK中key的選擇只有UITransitionContextFromViewControllerKey和UITransitionContextToViewControllerKey兩種蔫磨,分別表示將要切出和切入的VC。
3. -(CGRect)initialFrameForViewController:(UIViewController *)vc; 某個(gè)VC的初始位置圃伶,可以用來(lái)做動(dòng)畫的計(jì)算堤如。
4. -(CGRect)finalFrameForViewController:(UIViewController *)vc; 與上面的方法對(duì)應(yīng)蒲列,得到切換結(jié)束時(shí)某個(gè)VC應(yīng)在的frame。
5. -(void)completeTransition:(BOOL)didComplete; 向這個(gè)context報(bào)告切換已經(jīng)完成搀罢。
@protocol?UIViewControllerAnimatedTransitioning
這個(gè)接口負(fù)責(zé)切換的具體內(nèi)容蝗岖,也即“切換中應(yīng)該發(fā)生什么”。開(kāi)發(fā)者在做自定義切換效果時(shí)大部分代碼會(huì)是用來(lái)實(shí)現(xiàn)這個(gè)接口榔至。它只有兩個(gè)方法需要我們實(shí)現(xiàn):
1. -(NSTimeInterval)transitionDuration:(id < UIViewControllerContextTransitioning >)transitionContext; 系統(tǒng)給出一個(gè)切換上下文剪侮,我們根據(jù)上下文環(huán)境返回這個(gè)切換所需要的花費(fèi)時(shí)間(一般就返回動(dòng)畫的時(shí)間就好了,SDK會(huì)用這個(gè)時(shí)間來(lái)在百分比驅(qū)動(dòng)的切換中進(jìn)行幀的計(jì)算洛退,后面再詳細(xì)展開(kāi))。
2. -(void)animateTransition:(id < UIViewControllerContextTransitioning >)transitionContext; 在進(jìn)行切換的時(shí)候?qū)⒄{(diào)用該方法杰标,我們對(duì)于切換時(shí)的UIView的設(shè)置和動(dòng)畫都在這個(gè)方法中完成兵怯。
@protocol?UIViewControllerTransitioningDelegate
這個(gè)接口的作用比較簡(jiǎn)單單一,在需要VC切換的時(shí)候系統(tǒng)會(huì)像實(shí)現(xiàn)了這個(gè)接口的對(duì)象詢問(wèn)是否需要使用自定義的切換效果腔剂。這個(gè)接口共有四個(gè)類似的方法:
1. -(id< UIViewControllerAnimatedTransitioning >)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source;
2. -(id< UIViewControllerAnimatedTransitioning >)animationControllerForDismissedController:(UIViewController *)dismissed;
3. -(id< UIViewControllerInteractiveTransitioning >)interactionControllerForPresentation:(id < UIViewControllerAnimatedTransitioning >)animator;
4. -(id< UIViewControllerInteractiveTransitioning >)interactionControllerForDismissal:(id < UIViewControllerAnimatedTransitioning >)animator;
前兩個(gè)方法是針對(duì)動(dòng)畫切換的媒区,我們需要分別在呈現(xiàn)VC和解散VC時(shí),給出一個(gè)實(shí)現(xiàn)了UIViewControllerAnimatedTransitioning接口的對(duì)象(其中包含切換時(shí)長(zhǎng)和如何切換)掸犬。后兩個(gè)方法涉及交互式切換袜漩,之后再說(shuō)。
介紹了理論上的東西湾碎,我們來(lái)實(shí)現(xiàn)一下宙攻,Demo來(lái)了~~
首先我們需要新建一個(gè)實(shí)現(xiàn)了UIViewControllerAnimatedTransitioning協(xié)議的類。
解釋一下這個(gè)實(shí)現(xiàn):
我們首先需要得到參與切換的兩個(gè)ViewController的信息介褥,使用context的方法拿到它們的參照座掘;
對(duì)于要呈現(xiàn)的VC,我們希望它從屏幕下方出現(xiàn)柔滔,因此將初始位置設(shè)置到屏幕下邊緣溢陪;
將view添加到containerView中;
開(kāi)始動(dòng)畫睛廊。這里的動(dòng)畫時(shí)間長(zhǎng)度和切換時(shí)間長(zhǎng)度一致形真,都為0.8s。usingSpringWithDamping的UIView動(dòng)畫API是iOS7新加入的超全,描述了一個(gè)模擬彈簧動(dòng)作的動(dòng)畫曲線咆霜,我們?cè)谶@里只做使用,更多信息可以參看相關(guān)文檔卵迂;(順便多說(shuō)一句裕便,iOS7中對(duì)UIView動(dòng)畫添加了一個(gè)很方便的Category,UIViewKeyframeAnimations见咒。使用其中方法可以為UIView動(dòng)畫添加關(guān)鍵幀動(dòng)畫)
在動(dòng)畫結(jié)束后我們必須向context報(bào)告VC切換完成偿衰,是否成功(在這里的動(dòng)畫切換中,沒(méi)有失敗的可能性,因此直接pass一個(gè)YES過(guò)去)下翎。系統(tǒng)在接收到這個(gè)消息后缤言,將對(duì)VC狀態(tài)進(jìn)行維護(hù)。
接下來(lái)我們實(shí)現(xiàn)一個(gè)UIViewControllerTransitioningDelegate视事,應(yīng)該就能讓它工作了胆萧。我們現(xiàn)在在ViewController當(dāng)中來(lái)直接實(shí)現(xiàn)這個(gè)接口。如下
參考https://onevcat.com/2013/10/vc-transition-in-ios7/