iOS自定義轉(zhuǎn)場(chǎng)動(dòng)畫(huà)

關(guān)于iOS的轉(zhuǎn)場(chǎng)動(dòng)畫(huà)的實(shí)現(xiàn):

轉(zhuǎn)場(chǎng)動(dòng)畫(huà)實(shí)際上就是對(duì)View添加的轉(zhuǎn)場(chǎng)效果,在CATransiton就已經(jīng)給我們提供了豐富的事例

所以ViewController控制器之間的轉(zhuǎn)場(chǎng),其實(shí)還是對(duì)VC.view的操作,不過(guò)因?yàn)閂iewController的層級(jí)更復(fù)雜一些,所以需要先進(jìn)行一些其他的操作。

在實(shí)現(xiàn)自定義轉(zhuǎn)場(chǎng)動(dòng)畫(huà)之前,我們需要先了解實(shí)現(xiàn)ViewController轉(zhuǎn)場(chǎng)動(dòng)畫(huà)執(zhí)行的流程。

整體流程大致可以分為三步:

第一步:調(diào)用系統(tǒng)push/pop或者present/dismiss方法,獲取到VC跳轉(zhuǎn)的代理方法

第二步:在系統(tǒng)跳轉(zhuǎn)代理方法中,提供一個(gè)控制兩個(gè)View的實(shí)例對(duì)象,作為View轉(zhuǎn)場(chǎng)動(dòng)畫(huà)的載體

第三部:實(shí)現(xiàn)自定義動(dòng)畫(huà)(UIViewAnimation或者CAAnimation),并添加到這個(gè)實(shí)例中

接下來(lái)對(duì)這三步進(jìn)行詳細(xì)說(shuō)明:

1.首先實(shí)現(xiàn)第一步,在push/pop時(shí)獲取的到系統(tǒng)執(zhí)行轉(zhuǎn)場(chǎng)的代理方法:

這里先給ViewController添加了一個(gè)分類(lèi)Transition,用來(lái)統(tǒng)一調(diào)用push/present方法。transitionManager是從外部傳進(jìn)來(lái)的實(shí)例對(duì)象,后面會(huì)講到。

在分類(lèi)實(shí)現(xiàn)自定義的跳轉(zhuǎn)方法

從上圖可以看到,在兩個(gè)跳轉(zhuǎn)方法中都設(shè)置了delegate代理對(duì)象為transitionManager。點(diǎn)進(jìn)去查看源碼后,發(fā)現(xiàn)系統(tǒng)給ViewController提供了一個(gè)分類(lèi):UIViewControllerTransitioning

在上圖中可以看到,分類(lèi)中包含了一個(gè)UIViewControllerTransitioningDelegate協(xié)議,這個(gè)協(xié)議就是我們獲取系統(tǒng)push/present代理方法的關(guān)鍵,只要我們給transitioningDelegate屬性設(shè)置代理對(duì)象,就能獲取到系統(tǒng)跳轉(zhuǎn)的代理方法。上圖中只給出了ViewController的情況,如果是NavigationController類(lèi),協(xié)議就是UINavigationControllerDelegate,需要給UINavigationControllerDelegate設(shè)置代理對(duì)象。

下面我們新建一個(gè)繼承自NSObject的類(lèi):TransitionManager類(lèi),上面transitionManager就是這個(gè)類(lèi)的實(shí)例對(duì)象。并且遵守UINavigationControllerDelegateUIViewControllerTransitioningDelegate這兩個(gè)協(xié)議。

在TransitionManager中,分別實(shí)現(xiàn)協(xié)議中的中轉(zhuǎn)場(chǎng)代理方法

1.model模態(tài)視圖present/dismiss方法

2.push/pop視圖方法

這樣第一步我們就獲取到了VC跳轉(zhuǎn)的代理方法。

2.接著是第二步:獲取載體實(shí)例

在上面截取的部分代碼中不難發(fā)現(xiàn),在獲取到系統(tǒng)跳轉(zhuǎn)方法以后,我們都返回了一個(gè)transitionContext實(shí)例對(duì)象,這里使用transitionContext對(duì)象來(lái)作為實(shí)現(xiàn)轉(zhuǎn)場(chǎng)動(dòng)畫(huà)載體實(shí)例對(duì)象。

跟第一步一樣,我們還是要先創(chuàng)建一個(gè)繼承自NSObject的類(lèi):TransitionContext類(lèi),并且遵守了UIViewControllerContextTransitioning這個(gè)協(xié)議,這個(gè)協(xié)議就是我們獲取載體實(shí)例的關(guān)鍵。

遵守了這個(gè)協(xié)議以后,在.m文件中實(shí)現(xiàn)下面的系統(tǒng)方法,就能獲取到transitionContext對(duì)象作為執(zhí)行view轉(zhuǎn)場(chǎng)動(dòng)畫(huà)的載體,我們還給這個(gè)類(lèi)添加了一個(gè)block屬性,用于回調(diào)獲取到的這個(gè)載體實(shí)例。

接下來(lái)就是最后一步了。

3.第三步:實(shí)現(xiàn)轉(zhuǎn)場(chǎng)動(dòng)畫(huà)

在第一步的跳轉(zhuǎn)代理方法中,我們返回了一個(gè)transitionContext對(duì)象,其實(shí)這個(gè)對(duì)象就是由第二步的block回調(diào)得到?,F(xiàn)在將使用這個(gè)對(duì)象來(lái)實(shí)現(xiàn)我們的轉(zhuǎn)場(chǎng)動(dòng)畫(huà)。使用懶加載初始化TransitionManager的中定義的TransitionContext實(shí)例對(duì)象

在TransitionManager的.h文件中,還定義了setToAnimation:和setBackAnimation:兩個(gè)方法。在這兩個(gè)方法中來(lái)實(shí)現(xiàn)轉(zhuǎn)場(chǎng)動(dòng)畫(huà)的具體動(dòng)畫(huà)代碼。

但是直接在TransitionManager中編寫(xiě),會(huì)讓TransitionManager變得十分臃腫,所以對(duì)于每一個(gè)具體轉(zhuǎn)場(chǎng)動(dòng)畫(huà)的實(shí)現(xiàn),這里都會(huì)新建一個(gè)繼承自TransitionManager的子類(lèi),來(lái)專(zhuān)門(mén)實(shí)現(xiàn)setBackAnimation和setBackAnimation轉(zhuǎn)場(chǎng)動(dòng)畫(huà)的具體代碼。

項(xiàng)目中創(chuàng)建一個(gè)繼承自TransitionManager的類(lèi):CircleSpreadAnimation類(lèi),自定義一個(gè)實(shí)例化方法。

實(shí)現(xiàn)setToAnimation和setBackAnimation。

這里代碼較多,只貼出了一少部分。接下來(lái)就是如何調(diào)用

這里定義了兩個(gè)控制器CircleSpreadFromViewController、CircleSpreadToViewController,在CircleSpreadFromViewController傳入了點(diǎn)擊位置、動(dòng)畫(huà)初始半徑和動(dòng)畫(huà)持續(xù)時(shí)間,一個(gè)完整的轉(zhuǎn)場(chǎng)動(dòng)畫(huà)就完成了。

使用上面的系統(tǒng)協(xié)議,基本上就能實(shí)現(xiàn)自定義轉(zhuǎn)場(chǎng)動(dòng)畫(huà),這里是代碼部分

除此之外,在第一步獲取系統(tǒng)跳轉(zhuǎn)時(shí),也可以使用runtime的Method_ExchangeImplementations,替換系統(tǒng)push/present方法。后面的第二、三步思路不變。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容