0行代碼集成非死book和推ter的Modal動畫

wlhd3000 8年前發布 | 10K 次閱讀 IOS iOS開發 移動開發

用過非死book和推ter的同學應該尤其喜歡他們的動畫,但是動人心弦的動畫都是用時間堆出來的,可是程序員的時間... 各位同學,寫完代碼,就去陪老婆吃一頓飯吧,程序員老婆不容易。

現在進入正題。沒錯,就是告訴你0行代碼擁有非死book和推ter這個動畫。

0行代碼集成非死book和推ter的Modal動畫

要實現這個功能分兩步走:第一步,先實現這個動畫。第二步,0行代碼集成到項目。也就是,你不用改原有項目的任何代碼,只要把寫好的動畫代碼拖進項目,以后所有的Modal就擁有這個動畫了。

  - (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^ __nullable)(void))completion

好,準備好了嗎?現在開始。

第一步:先實現這個動畫

  • 首先我們來分析一下這個動畫,這個動畫就是在Modal的時候拿到當前控制器的View,然后在Modal的過程中將這個View的尺寸縮小。然后在Dismiss的時候拿到這個View,將它尺寸恢復成原有的大小。就這么多了。

  • 怎么在modal動畫中拿到當前的控制器的View?這個很簡單,只要你設置動畫樣式為自定義,并且成為彈出動畫的代理,就像這樣:

    self.modalTransitionStyle = UIModalPresentationCustom;
    viewControllerToPresent.transitioningDelegate = self;

    然后在代理方法中,會詢問轉場動畫的提供者,此時,你再去新建一個JPTransitionManager作為轉場動畫的提供者。

    // 詢問轉場動畫的提供者
    - (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source;
    
    - (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed;
  • 在這個轉場動畫的提供者里,我們繼承NSObject,然后遵守
    UIViewControllerAnimatedTransitioning協議,然后實現協議中這兩個方法:

    - (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext;
    
    - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext;

    第一個方法是詢問動畫的時長的。第二個方法中我們可以拿到準備做Modal動畫的上下文transitionContext,在上下文中我們就可以通過:UITransitionContextFromViewControllerKey和UITransitionContextToViewControllerKey兩個key拿到當前的控制器和即將彈出的控制器。

  • 控制器都拿到了,我們就可以拿到控制器對應的View進行動畫了。

第二步:0行代碼集成到項目

為什么要強調0行代碼集成到項目?

  • 剛開始寫代碼的時候,項目老大并沒有說要這個動畫,你項目都快結束了,他說這個動畫挺好,我們也做一個吧(程序員轉過身:XXX臟話)。這個時候你已經寫了幾百個Modal動畫的代碼了,你不可能一個一個去找去改吧?
  • 幾百行你改完了,你以為終于完事了,這件事就過去了,結果產品經理一個月以后又跑過來說,這個功能我們還是砍掉吧。(程序員大聲:XXXXXX很臟的話)。

所以,這個時候低耦合易集成就顯得特別重要。

為了處理這樣的需求,所以采用hook方案,結合runtime來解決。hook就是鉤子的意思。

  • 我們要用這個鉤子把系統所有的Modal動畫的實現都鉤出來,然后再把我們自己寫的pop動畫也給鉤出來。
  • 然后再運用動態方法交換,將這系統的Modal動畫和自己的pop動畫的實現相互替換。
  • 所以以后,我們再調用系統的Modal動畫的時候,實際上會去方法實現里找我們自己的pop動畫去執行。這也就是為什么可以0行代碼集成這個功能的原因。
  • 也有可能我們在某些情況下不需要pop動畫,比如說照片瀏覽器。這種情況很少,所以你只需要寫很少的代碼,去調用我們自己的pop動畫。當調用我們自己的pop動畫的時候,我們的鉤子會去找系統的Modal動畫去執行。

思路就到這里了,具體的實現細節,還需要您自己去Github下載 demo

One more thing ?

如果您對“hook技術”想有一個相對全面的了解,或許可以參見我的另外一篇文章“1行代碼快速集成按鈕延時處理(hook實戰)”。我在這篇文章詳細的闡述了鄙人對“hook技術”的見解。


 

來自:http://www.jianshu.com/p/910d7825f06a

 本文由用戶 wlhd3000 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!