當彈出一個view controller時,UIKit提供了一些標準轉換動畫,而且也支持用戶自定義的動畫效果。 app
1 UIView動畫 ide
UIView是自帶動畫實現功能,其中有兩種方式實現: 函數
1) animateWithDuration系列方法 測試
2) transitionFromViewController方法 動畫
1.1 animateWithDuration ui
只要在該方法的animations block中修改UIView的動畫屬性,那麼便可實現動畫變換,因此爲container viewController中實現不一樣view controller之間的動畫切換,只要改變了UIView的動畫屬性便可以實現變換。 spa
如在調用viewMove方法以前,fromVC爲顯示狀態,而toVC爲未顯示狀態。因此調用時便可實現動畫切換: code
1.2 transitionFromViewController 對象
UIView同時提供了視圖切換方法,同時可支持動畫變換,即transitionFromViewController方法。從而能夠在container viewController中調用該方法來實現視圖的變換。 blog
如在當前viewController有兩個子視圖控制器:fromVC和toVC,而且fromVC爲顯示狀態。因此能夠調用transitionFromViewController方法來實現動畫切換。
2 轉換動畫次序
轉換動畫是交互兩個view controller的內容,其中存在兩種轉換類型:彈出(presentation)和撤回(dismissal)。
1) presentation:這種動畫是指在app的view controller層次結構中添加新的view controller;
2) dismissal:這種動畫是指從app的view controller層次結構中移除view controller。
2.1 轉換delegate
轉換delegate是一個實現了UIViewControllerTransitioningDelegate協議的對象,其工做是提供以下之一的對象:
1) Animator對象:
該對象是實現了UIViewControllerAnimatedTransitioning協議的實體。其功能是負責以動畫的形式顯示或隱藏view controller的視圖。轉換delegate向那些進行presenting 和dismissing操做的實體提供Animator對象。
2) Interactive animator對象:
該對象是實現了UIViewControllerInteractiveTransitioning協議的實體。其也是實現動畫操做,但可在動畫過程當中與用戶進行事件交互。
3) Presentation controller:
當view controller在屏幕時,presentation controller負責管理彈出(presentation)的樣式。系統已提供了一些內置樣式,同時也支持用戶自定義更多的presentation樣式。
若要實現自定義動畫,須要設置新彈出view controller的transitioningDelegate屬性爲遵照UIViewControllerTransitioningDelegate協議的對象,同時要修改新彈出view controller的modalPresentationStyle屬性爲常量UIModalPresentationCustom。
圖 312 The custom presentation and animator objects
如圖 312所示,綠色表示 Presenting view controller(主動彈出),藍色爲Presented view controller(被動彈出),被彈出的VC有個Transitioning Delegate屬性,經過這個屬性可得到Animator、Interactive Animator和Presentation Controller對象。
2.2 執行時序
1) Present view controller
當被彈出view controller的transitioningDelegate屬性是一個有效對象時,UIKit將按指定的動畫彈出這個view controller。在準備階段UIKit會從UIViewControllerTransitioningDelegate協議(稱爲轉換delegate)調用錯誤! 超連接引用無效。:方法,從而來查詢指定的動畫對象,若該對象有效,則UIKit會按以下步驟執行:
a) UIKit會調用轉換delegate的interactionControllerForPresentation:方法,若該方法返回nil,那麼UIKit將不與用戶進行交互的執行動畫。
b) UIKit調用animator對象的transitionDuration:方法來查詢動畫的執行時間。
c) UIKit調用相應方法開始執行動畫:
*若爲非交互動畫,則調用animator對象的animateTransition:方法;
*若爲交互動畫,則調用interactive animator的startInteractiveTransition:方法。
d) UIKit等待動畫對象調用context transitioning的completeTransition:方法來等完成動畫。
在自定義的動畫中,須要手動調用transitionContext對象的completeTransition方法來完成動畫操做。
2) Dismiss view controller
當消除一個view controller時,UIKit會調用UIViewControllerTransitioningDelegate協議(稱爲轉換delegate)中的animationControllerForDismissedController:方法,並按以下步驟執行程序:
a) UIKit會調用轉換delegate的interactionControllerForDismissal:方法,若該方法返回nil,那麼UIKit將不與用戶進行交互的執行動畫。
b) UIKit調用animator對象的transitionDuration:方法來查詢動畫的執行時間。
c) UIKit調用相應方法開始執行動畫:
*若爲非交互動畫,則調用animator對象的animateTransition:方法;
*若爲交互動畫,則調用interactive animator的startInteractiveTransition:方法。
d) UIKit等待動畫對象調用context transitioning的completeTransition:方法來等完成動畫。
在自定義的動畫中,須要手動調用transitionContext對象的completeTransition方法來完成動畫操做。
注意:
當在實現動畫體結束時必須手動調用completeTransition:方法來結束操做。
2.3 轉換Context對象
在轉換動畫開始以前,UIKit會建立一個transitioning context對象,並將一些如何執行動畫的信息填充到該對象中,這些信息包括Presenting view controller、Presented view controller、container view controller,以及是否與用戶進行交互的信息。其中context對象是實現了UIViewControllerContextTransitioning協議。
如圖 313所示,白色方塊表示container view(不是controller)、綠色表示Presenting view controller、藍色表示Presented view controller,虛線表示引用,實線表示方法。Animator對象經過animateTransition:方法得到context對象,而context經過自身的containerView:方法得到container VC。
圖 313 The transitioning context object
2.4 轉換Coordinator對象
無論是內置的轉換仍是自定義的轉換,UIKit都會建立一個Coordinator對象幫助動畫的執行。除了Present和dismissal view controller外,轉換還可能發生在view cotroller的frame發生變化時。在動畫過程當中,能夠經過Coordinator對象得到一些信息。如圖 314所示,圖形語義與圖 313同樣。
圖 314 The transition coordinator objects
3 使用自定義動畫
使用自定義的動畫實現Present(彈出)view controller,須要進行以下操做:
1)建立一個Presented view controller;
2)建立一個已經實現了UIViewControllerTransitioningDelegate協議的對象,並將其賦值給Presented view controller對象的transitioningDelegate屬性。
3)調用presentViewController:animated:completion:方法彈出新的view controller,而且須要將YES傳遞給該方法的animated參數。
4 實現轉換delegate
如圖 312所示,轉換delegate的功能是爲Present和dismissal操做,提供Animator、Interactive animator
和Presentation controller三種對象。因此實現UIViewControllerTransitioningDelegate協議也就是實現那些可以獲取這三個對象的方法。
以下是實現一個能獲取Animator對象的方法:
5 實現動畫delegate
爲了實現UIViewControllerAnimatedTransitioning協議須要實現兩個方法:
1) transitionDuration: transitionContext:返回動畫持續的時間;
2) animateTransition: transitionContext:執行具體動畫的方法;
其中animateTransition方法是重點,主要工做都是在實現該方法中,其中能夠將實現該方法分爲以下三個步驟:
a) 獲取與動畫有關的參數;
b) 經過core Animation或UIView animation實現動畫;
c) 完成動畫操做。
5.1 獲取參數
當實現animateTransition方法時,其會傳遞一個transitionContext參數,能夠經過這個參數可以得到與動畫相關的信息:
1) 經過viewControllerForKey:方法得到在轉換時的"from"和"to" view controller;
2) 經過containerView方法得到動畫的超類,從而將全部的子view添加到這個container view中;
3) 經過viewForKey:方法得到被添加或被刪除的view,其中在轉換過程當中要麼是被添加,要麼是被刪除的view。
4) 經過finalFrameForViewController:方法得到最後被添加或刪除後view 的frame矩形。
因爲動畫對象能夠向Present和dismissal操做提供動畫,因此經過transitionContext獲取的"from"和"to" view controller語義有些差別。如圖 315所示,當執行Present操做時,是將"to" view controller添加到container層次結構中;而當執行dismissal操做時,是將"from" view controller從container層次結構中移除。
圖 315 The from and to objects
5.2 實現動畫
爲了實現動畫效果,在animateTransition:方法中必須完成兩部分的內容:
a) 以動畫的形式修改presented view controller中的view位置;
b) 將presented view controller中的view添加到container view的層次結構中。
1) Presentation 動畫
對於執行彈出動畫,能夠按以下步驟完成配置:
a) 經過transitionContext對象的viewControllerForKey: 和viewForKey:方法得到view controllers 和views對象。
b) 設置"to" view的起始位置,同時也可修改其它屬性值。
c) 經過transitionContext對象的finalFrameForViewController:方法獲取"to" view的最終位置。
d) 將 "to" view添加到container view的層次結構中。
e) 建立動畫
2) Dismissal動畫
消除view controller的動畫與彈出的操做類似,一樣也可按以下步驟完成配置:
a)經過transitionContext對象的viewControllerForKey: 和viewForKey:方法得到view controllers 和views對象。
b) 計算presented view controller的view(便是"from" view)最終位置,該view爲被清除的view。
c) 仍是將 "to" view添加爲container view的子view。
d) 建立動畫
5.3 測試實例
1) 場景
如要實現圖 316所示的兩種動畫操做,在A視圖中彈出B視圖,而且能夠在B視圖將其自身推出返回到A視圖。
圖 316 A custom presentation and dismissal
2) 實現動畫Delegate
用戶須要建立已經實現了UIViewControllerAnimatedTransitioning協議的對象,以下是MyAnimator類的具體實現,在該類的animateTransition:方法中實現了兩種動畫效果(Presentation和Dismissal),其中Presenting爲YES時,表示實現Presentation操做;當Presenting爲NO時,表示實現Dismissal操做,這個Presenting在構造函數中進行初始化。固然也能夠將兩種操做分別實如今不一樣的對象中。
3) 實現轉換Delegate
在彈出動畫前,須要先給Presented view controller對象設置transitioningDelegate屬性,而設置的對象爲UIViewControllerTransitioningDelegate協議的實現類。以下是一種實現方式,因爲被彈出的view controller有兩種動畫效果(Presentation和Dismissal),因此須要實現animationControllerForPresentedController和animationControllerForDismissedController方法分別彈出兩種不一樣的動畫對象。
4) 實現彈出操做
上述的轉換delegate和動畫delegate都已經實現完成,接下來就是要實現轉換視圖的響應方法。即firstViewController爲圖 316的A視圖控制器,而thirdViewController爲圖 316的B視圖控制器。而customAnimation:方法爲按鈕的響應方法,在該方法中調用presentViewController方法來彈出thirdViewController視圖(即B視圖)。
其中須要注意的是mtd屬性,不能將其聲明爲customAnimation方法內的局部變量,不然將致使Dismissal操做不能實現動畫,由於在該方法推出後,mtd變量的生命週期將結束,從而在Dismissal操做時其已經無效,因此這裏將mtd聲明爲成員屬性,固然若firstViewController類自身實現了UIViewControllerAnimatedTransitioning協議,那麼能夠將transitioningDelegate設置爲self。
5) 實現退出操做
在被彈出視圖(B視圖)中,只需實現退出按鈕的響應方法(dismissal),從而在該方法中調用dismissViewControllerAnimated方法推出操做。
6 添加交互對象
UIKit支持添加一個交互對象,經過這個對象用戶能在進行彈出等操做時,控制動畫的動做。爲轉換delegate添加一個交互對象也很是簡單,只需在其interactionControllerForPresentation方法中返回一個遵照UIViewControllerInteractiveTransitioning協議的對象便可。能夠直接實現該協議,也能夠繼承UIPercentDrivenInteractiveTransition類,但都需重載startInteractiveTransition方法。
最後須要注意的是,因爲轉換動畫仍是執行UIViewControllerTransitioningDelegate協議中animationControllerForPresentedController方法返回的對象,但動畫開始執行的時間還是在調用finishInteractiveTransition方法後。
以下所示的實例:
1) 實例場景
用戶在點擊視圖的按鈕後,須要再點擊視圖中的空白區域,才能實現轉換及動畫。從而本例只是在3.3.5.3小節所示的基礎上添加一個交互對象,因此對其它內容都無需修改,只是添加的交互類myInteractiveAnimator,及在myTransitioningDelegate類中添加了一個interactionControllerForPresentation方法,在該方法中返回一個交互對象。
2) 實現交互類
本例採用繼承UIPercentDrivenInteractiveTransition類的方式實現交互,從而實現了startInteractiveTransition方法。在該方法中添加了一個點擊手勢識別器,並在響應方法中啓動動畫轉換。
3) 返回交互對象
以下是在3.3.5.3小節所示的myTransitioningDelegate類基礎上添加了interactionControllerForPresentation方法,其它方法都是原來的內容。
iOS UIKit:viewController文章參考文獻
[1] View Controller Programming Guide for IOS
[3] 建立Unwind Segue
[4] UIViewControllerTransitioningDelegate Protocol Reference.
[5] UIViewControllerContextTransitioning Protocol Reference.
[6] UIViewControllerInteractiveTransitioning Protocol Referrence