幾句程式碼快速整合自定義轉場效果+ 全手勢驅動

發表於2016-07-09

寫在前面

在簡書寫完第一篇的自定義轉場文章後,已經很久沒有碰過轉場了,畢竟在公司,功能實現才是最重要的,這些轉場的動效,只能是點睛之筆,不太容易被重視,不過我的第一篇文章還是很多人的喜歡和討論,很多人還提出些建議,非常感謝大家,這是我第一篇文章的地址自定義轉場動畫,裡面包含了一些轉場的基礎知識,這篇文章我就不再討論這些基礎知識了。
為什麼會有這第二篇文章,主要原因有如下幾點:

1、能不能更簡單?當我很久沒有使用轉場的時候,再次來使用它,感覺還是比較煩瑣,有一大堆記不住的長長的代理方法,都要去copy,長長的代理方法也把控制器弄得有點亂,雖然蘋果已經將整個過程充分解耦了,我在想,要是能簡單的一兩句話就能整合轉場效果多好,或者通過繼承和複寫一兩個方法就能輕鬆實現自己的轉場效果,無需關注轉場邏輯,只需關注動畫邏輯

2、閃爍和生硬?在第一篇文章中有人提到的部分的bug,比如小圓點擴散效果,如果手勢在中途取消,不會有取消動畫,非常生硬,而且會有閃爍的bug,我在想能不能解決這兩個問題,強迫症接受不了o(╯□╰)o,我現在找到了一個比較好的方式來解決問題,原理和對比圖會在後面給出

3、能不能多新增一些效果?所以我把自己寫的效果封裝,再參照網路一些效果,總過新增了將近20個效果

4、手勢萬歲!任何效果我都想能夠手勢驅動

效果圖(圖比較多,請手機使用者慎重,可下載demo真機執行效果更好)

截圖中,右上角的switch開關代表push和present,所有效果都支援手勢,我就不一一演示了

1、CircleSpreadTransition 小圓點擴散

幾句程式碼快速整合自定義轉場效果+ 全手勢驅動

CircleSpreadTransition.gif

2、MagicMoveTransition 神奇移動

 

幾句程式碼快速整合自定義轉場效果+ 全手勢驅動

MagicMoveTransition1.gif

幾句程式碼快速整合自定義轉場效果+ 全手勢驅動

MagicMoveTransition2.gif

3、XWDrawerAnimator 抽屜效果,仿照QQ和淘寶

 

幾句程式碼快速整合自定義轉場效果+ 全手勢驅動

XWDrawerAnimator1.gif

幾句程式碼快速整合自定義轉場效果+ 全手勢驅動

XWDrawerAnimator2.gif

4、XWCoolAnimator 自定義一些效果

 

幾句程式碼快速整合自定義轉場效果+ 全手勢驅動

XWCoolAnimator2.gif

幾句程式碼快速整合自定義轉場效果+ 全手勢驅動

XWCoolAnimator1.gif

幾句程式碼快速整合自定義轉場效果+ 全手勢驅動

XWCoolAnimator3.gif

幾句程式碼快速整合自定義轉場效果+ 全手勢驅動

XWCoolAnimator4.gif

幾句程式碼快速整合自定義轉場效果+ 全手勢驅動

XWCoolAnimator5.gif

幾句程式碼快速整合自定義轉場效果+ 全手勢驅動

XWCoolAnimator6.gif

幾句程式碼快速整合自定義轉場效果+ 全手勢驅動

XWCoolAnimator7.gif

5、XWFilterAnimator 通過CIFilter濾鏡自定義一些效果,請在真機上執行

幾句程式碼快速整合自定義轉場效果+ 全手勢驅動

XWFilterAnimator1.gif

幾句程式碼快速整合自定義轉場效果+ 全手勢驅動

XWFilterAnimator6.gif

幾句程式碼快速整合自定義轉場效果+ 全手勢驅動

XWFilterAnimator5.gif

幾句程式碼快速整合自定義轉場效果+ 全手勢驅動

XWFilterAnimator4.gif

幾句程式碼快速整合自定義轉場效果+ 全手勢驅動

XWFilterAnimator3.gif

幾句程式碼快速整合自定義轉場效果+ 全手勢驅動

XWFilterAnimator2.gif

幾句程式碼快速整合自定義轉場效果+ 全手勢驅動

XWFilterAnimator8.gif

幾句程式碼快速整合自定義轉場效果+ 全手勢驅動

XWFilterAnimator7.gif

如何使用

1、git地址:幾句程式碼快速整合自定義轉場效果+ 全手勢驅動,clone後將整個XWTranstion資料夾匯入工程

2、匯入UINavigationController+XWTransition.h或者UIViewController+XWTransition.h兩個分類

3、選擇你需要的效果器進行根據初始化方法進行初始化,比如下面的小圓點擴散,初始化指定開始圓心和半徑

4、通過初始化的效果器轉場,根據分類提供的方法進行push或者present,就完成了!

手勢驅動

1、在UIViewController+XWTransition.h分類中提供了兩個方法,用來註冊手勢驅動,在viewDidLoad的時候呼叫註冊手勢就可以了,詳見demo,注意避免迴圈引用,手勢支援邊緣屬性

2、事例程式碼

關於神奇移動效果

1、在UIViewController+XWTransition.h分類中提供了三個關於神奇移動的方法,你需要在轉場前和轉場後的控制器中分別註冊神奇移動前後的檢視(用來告知神奇移動前後的frame),然後通過神奇移動效果器就可以觸發神奇移動轉場了

2、事例程式碼

3、轉場中存在cell,由於在轉場過程中cell還沒有載入,所以無法註冊cell為神奇移動檢視,這種情況需要生產一個零時檢視註冊為轉場檢視來使用,具體請參考demo中的九宮格例子

4、關於提供的imageMode屬性:在神奇移動中,有個問題,就是移動中的臨時檢視一般都是用截圖大法截圖而來的,但是如果從從小圖變成大圖,由於截圖為小圖截圖,變大過程中會有模糊的現象,如果設定了該屬性,我會對神奇移動檢視中的包含了image的檢視進行檢測,如果能檢測到image則直接取image,而不截圖,就能解決模糊的問題,程式碼如下

關於抽屜效果的全屏拖動

1、抽屜效果由於註冊的手勢都是在控制器的的檢視上,如果做QQ設定介面的效果,不可能在toVC之外點選和拖動能夠back,我的思路是會在toVC沒有覆蓋的區域新增一個透明檢視,給透明檢視加上點選和拖動手勢,具體程式碼如下

解決動畫生硬

1、先看小圓點效果的例子,前面是解決前寫的,後面是現在的

未解決

幾句程式碼快速整合自定義轉場效果+ 全手勢驅動

小圓點未開啟timer.gif

解決後

幾句程式碼快速整合自定義轉場效果+ 全手勢驅動

小圓開啟timer.gif

2、問題原因:在手勢結束後該效果不會動畫的過渡到成功或者失敗,而是整個轉場進度會直接update到0或者1,就木有動畫了

3、解決:在手指鬆開的時候,我會開啟一個CADisplayLink來不斷的重新整理整個轉場進度到1或者0,來達到動畫的效果,具體程式碼如下

解決閃爍問題

1、閃爍原因:在不使用UIView的動畫block時,我們直接為layer新增一個CAAnimtion,此時會先設定modelLayer為轉場成功的狀態,比如小圓點效果會設定path為大圓的path,但是如果轉場失敗,presentLayer依然會先變為modelLayer設定的成功值,然後動畫才結束,走我們的轉場失敗邏輯,所以就會閃爍

2、解決:我把手勢改變的一些關鍵狀態通過代理傳出來,在手勢結束前,我們如果檢查到失敗,可以先將modelLayer的值標記為失敗時候的值,也就是初始值,就解決了該問題

3、事例程式碼

關於coolTransiton

1、直接通過列舉初始化就有已經整合的部分效果,具體如下:

2、 cool轉場效果中的Portal、Fold、Explode效果的部分程式碼邏輯來源於ColinEberhardt/VCTransitionsLibrary,非常感謝作者,我只是將其進行了部分改動,以便對手勢的支援更加完善,裡面還有許多其他效果,本人經歷有限就沒有再整合進來了,大家可以自行檢視;cool轉場效果的Lines的想法來自於cinkster/HUAnimator, 非常感謝作者,但是由於作者在對toVC截圖採用了延遲的方式來處理,導致了不好處理的bug和一些手勢上的bug,對此我採用了另一種方式來解決截圖的問題,使用了layer的contentRect屬性,解決了發現的問題,相關程式碼請自行檢視

關於FilterTransition

1、XWFilterAnimator 全都是基於不同的CIFilter產生的一些濾鏡效果,貌似在模擬器無法執行這些效果,請在真機上測試,直接通過列舉初始化就有已經整合的部分效果,具體如下:

2、如果想要新增其他濾鏡轉場,可以嘗試我的FilterTransition中書寫分類的方式,只需要指定CIFilter和相關邏輯即可

關於自定義轉場效果

1、你只需要繼承於XWTransitionAnimator,就像我上面所有的效果器一樣,然後複寫需要的屬性和兩個必須的方法即可,然後你就可以使用你自定義的效果器轉場,XWTransitionAnimator標頭檔案如下:

2、這樣就只需要關心動畫的邏輯,其餘的事情就不用管了,不過如果遇到閃爍問題,你只需要複寫相關的手勢代理方法,就像我在小圓點轉場中一樣,因為XWTransitionAnimator預設是手勢管理者的代理,所以直接實現代理方法就好了

寫在最後

陸陸續續的就這些了,東西比較多,可能我的敘述也還有一定問題,某些內容可能描述的不太清楚,請大家多多參考demo,希望本文能讓大家以後再設計到自定義轉場的時候能夠迅速解決問題,再次複習一下地址幾句程式碼快速整合自定義轉場效果+ 全手勢驅動 ,如果對您有幫助歡迎給予star支援!

更新 2016-06-24

今天早上思考了一下,優化了一下DrawerAnimator,之前的toVC的frame不會隨著設定的distance改變,預設一般都是螢幕的寬和高,也就是說顯示之後,toVC的有一部分實際是在螢幕外面的,這對於後續的佈局是不太方便的,所以我修改了一下,現在toVC的frame是和設定的distance相關的,所看見的toVC的部分就是toVC的全部

更新 2016-07-05

1、今天發現了一個問題,就是在進行不同的效果多次push的時候,在pop的時候,之前的效果會失效,我修復了這個問題,請看截圖,上面是修復前,下面是修復後

幾句程式碼快速整合自定義轉場效果+ 全手勢驅動

修正之前.gif

幾句程式碼快速整合自定義轉場效果+ 全手勢驅動

修正之後.gif

可以看見,修復前,在最後一次back的時候,那個爆炸的效果已經失效了,
2、問題原因:在每次push時我會切換navigationController的delegate為當前效果器,從而能完成轉場效果的邏輯,所以多次push後,代理始終是最後一個效果器,而在pop的時候那個效果器隨著對應的pop操作已經被銷燬了,而代理並沒有切換為之前的爆炸效果器,所以自定義轉場就無法觸發了
3、解決:由於我每一個效果器是和被push出的VC繫結的,所以當被pushVC被銷燬的時候,效果器就會銷燬,此刻,應該去檢測一下代理,如果上一個VC存在效果器,則需要切換回該效果器,所以需要在pushVC的dealloc方法中需要對代理進行檢測和切換,為了達到目的,需要對VC的dealloc方法進行調劑,調劑的方法稍微有點複雜,具體請看我另一篇簡書文章:一句程式碼,更加優雅的呼叫KVO和通知中關於調劑dealloc方法的相關程式碼,在dealloc中新增了代理檢測和切換的方法來達到目的

相關文章