iOS自定義轉(zhuǎn)場動畫
首先介紹下iOS轉(zhuǎn)場動畫控制相關API
動畫控制器 (Animation Controllers)遵從UIViewControllerAnimatedTransitioning協(xié)議,并且負責實際執(zhí)行動畫。
交互控制器 (Interaction Controllers)通過遵從UIViewControllerInteractiveTransitioning協(xié)議來控制可交互式的轉(zhuǎn)場。
轉(zhuǎn)場代理 (Transitioning Delegates)根據(jù)不同的轉(zhuǎn)場類型方便的提供需要的動畫控制器和交互控制器。
轉(zhuǎn)場上下文 (Transitioning Contexts)定義了轉(zhuǎn)場時需要的元數(shù)據(jù),比如在轉(zhuǎn)場過程中所參與的視圖控制器和視圖的相關屬性。 轉(zhuǎn)場上下文對象遵從UIViewControllerContextTransitioning協(xié)議,并且這是由系統(tǒng)負責生成和提供的。
轉(zhuǎn)場協(xié)調(diào)器(Transition Coordinators)可以在運行轉(zhuǎn)場動畫時,并行的運行其他動畫。 轉(zhuǎn)場協(xié)調(diào)器遵從UIViewControllerTransitionCoordinator協(xié)議。
通過presentViewController:animated:completion:和dismissViewControllerAnimated:completion:這一組函數(shù)以模態(tài)視圖的方式展現(xiàn)、隱藏視圖。如果用到了navigationController,還可以調(diào)用pushViewController:animated:和popViewController這一組函數(shù)將新的視圖控制器壓棧、彈棧。這些都是系統(tǒng)默認動畫效果。
本文主要介紹presentView和navigationController兩種形式的自定義轉(zhuǎn)場動畫。第一部分是自己寫的,第二部分借用了蘋果官方代碼
1.簡單的轉(zhuǎn)場交互處理
帶導航的情況
在UINAVigationControllerDelegate的代理中有兩個方法是處理轉(zhuǎn)場動畫的

在第一個方法中需要返回一個遵循UIViewControllerAnimatedTransitioning代的OC對象
實現(xiàn)這個方法的時候 push和pop的時候都會調(diào)用
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext這個方法,你可以在這里處理一些自定義的情況
第二個代理方法需要返回一個遵循UIViewControllerInteractiveTransitioning協(xié)議的交互類 當這個方法有返回值的時候,會執(zhí)行
- (void)startInteractiveTransition:(id<UIViewControllerContextTransitioning>)transitionContext這個方法 你可以在這里做一些自定義情況
不帶導航的情況
當present做跳轉(zhuǎn)的時候需要在遵循UIViewControllerTransitioningDelegate的類內(nèi)實現(xiàn)下面這兩個方法 給出返回值

2.官方轉(zhuǎn)場交互處理
這部分引用了蘋果官方demo代碼的交互轉(zhuǎn)場部分
設置了toViewController的transitioningDelegate屬性并且present時,UIKit會從代理處獲取animator,其實這里還有一個細節(jié):UIKit還會調(diào)用代理的interactionControllerForPresentation:方法來獲取交互式控制器,如果得到了nil則執(zhí)行非交互式動畫,這就回到了上一節(jié)的內(nèi)容。
如果獲取到了不是nil的對象,那么UIKit不會調(diào)用animator的animateTransition方法,而是調(diào)用交互式控制器(還記得前面介紹動畫代理的示意圖么,交互式動畫控制器和animator是平級關系)的startInteractiveTransition:方法。-
所謂的交互式動畫,通常是基于手勢驅(qū)動,產(chǎn)生一個動畫完成的百分比來控制動畫效果(文章開頭的gif中第二個動畫效果)。整個動畫不再是一次性、連貫的完成,而是在任何時候都可以改變百分比甚至取消。這需要一個繼承自UIPercentDrivenInteractiveTransition的交互式動畫控制器和animator協(xié)同工作。這看上去是一個非常復雜的任務,但UIKit已經(jīng)封裝了足夠多細節(jié),我們只需要在交互式動畫控制器和中定義一個時間處理函數(shù)(比如處理滑動手勢),然后在接收到新的事件時,計算動畫完成的百分比并且調(diào)用updateInteractiveTransition來更新動畫進度即可。
image.png
本文demo地址
喜歡的話可以點個星星
本文參考文檔
https://juejin.im/post/5a309c466fb9a0451c3a6120
