• 同福彩票官网

  • 同福彩票官网

  • 同福彩票官网

  • 熱rang)拋ㄌ/h3>

同福彩票官网

作者︰  發布日期︰2020-02-26 03:08:30
Tag標簽︰轉(zhuan)場(chang)  版本  動畫  
  • 轉(zhuan)場(chang)動畫這事,說dao)虻?布虻? ke)以通過presentViewController:animated:completion:和dismissViewControllerAnimated:completion:這一組函(han)數(shu)以yue)L 油嫉姆絞秸瓜幀 yin)藏(cang)視圖。如果用到了navigationController,還可(ke)以調(diao)用pushViewController:animated:和popViewController這一組函(han)數(shu)將新(xin)的視圖控(kong)制器壓棧、彈棧。

    下圖中所(suo)有轉(zhuan)場(chang)動畫都是自定義(yi)的動畫,這些效果如果不用自定義(yi)動畫則(ze)很難甚(shen)至(zhi)無(wu)法實現︰


    demo演示

    由于錄屏的原(yuan)因,有些效果無(wu)法完全展現,比如它其(qi)實還支持(chi)橫屏。

    自定義(yi)轉(zhuan)場(chang)動畫的效果實現起(qi)來比較復(fu)雜,如果僅僅是拷貝(bei)一huan)菽芄輝誦械拇dai)碼(ma)卻不懂其(qi)中原(yuan)理,就有可(ke)能帶來各種隱(yin)藏(cang)的bug。本文(wen)由淺(qian)入深(shen)介紹下面幾個知識︰

    傳統的mu)ji)于閉包的實現方式及其(qi)缺點(dian)自定義(yi)present轉(zhuan)場(chang)動畫交(jiao)互式(Interactive)轉(zhuan)場(chang)動畫轉(zhuan)場(chang)協調(diao)器與UIModalPresentationCustomUINavigationController轉(zhuan)場(chang)動畫

    我為這篇教程(cheng)制作了一個demo,您可(ke)以去(qu)在我的github上clone下來︰CustomTransition,如果覺得有幫助還望給個star以示支持(chi)。本文(wen)以Swift+純代(dai)碼(ma)實現,對應的OC+Storyboard版本在demo中也可(ke)以找(zhao)到,那是隻果的官方示範(fan)代(dai)碼(ma),正確性更有保證(zheng)。demo中用到了CocoaPods,您也許(xu)需(xu)要執行pod install命(ming)令並(bing)打開.xcworkspace文(wen)件。

    在開始正式的教程(cheng)前(qian),您首先需(xu)要下載demo,在代(dai)碼(ma)面前(qian)文(wen)字(zi)是蒼白的mo)emo中包含的注釋足以解釋本文(wen)所(suo)有的知識點(dian)。其(qi)次,您還得了si)庹餳父霰塵jing)知識。

    同福彩票官网

    在代(dai)碼(ma)和文(wen)字(zi)中,經常會出現fromView和toView。如果錯誤(wu)的理解它們的含義(yi)會導(dao)致動畫邏輯完全錯誤(wu)。fromView表示當前(qian)視圖,toView表示要跳轉(zhuan)到的視圖。如果是從A視圖控(kong)制器present到B,則(ze)A是from,B是to。從B視圖控(kong)制器dismiss到A時,B變成(cheng)了from,A是to。用一張(zhang)圖表示︰


    from和to

    同福彩票官网

    這也是一組相對的概念,它容易zi)romView和toView混淆(xiao)。簡單來說,它不受present或dismiss的影響(xiang),如果是從A視圖控(kong)制器present到B,那麼A總是B的presentingViewController,B總是A的presentedViewController。

    同福彩票官网

    這是一個枚舉(ju)類型,表示present時動畫的類型。其(qi)中可(ke)以自定義(yi)動畫效果的只有兩(liang)種︰FullScreen和Custom,兩(liang)者的區別(bie)在于FullScreen會移除fromView,而Custom不會。比如文(wen)章開頭fan)if中,第三個動畫效果就是Custom。

    同福彩票官网

    最簡單的轉(zhuan)場(chang)動畫是使用transitionFromViewController方法︰


    傳統的轉(zhuan)場(chang)動畫實現

    這個方法雖然已經過時,但是對它的分析有助于後面知識的理解。它一共有6個參數(shu),前(qian)兩(liang)個表示從哪(na)個VC開始,跳轉(zhuan)到哪(na)個VC,中間兩(liang)個參數(shu)表示動畫的時間和選項。最後兩(liang)個參數(shu)表示動畫的具體(ti)實現細節和回調(diao)閉包。

    這六個參數(shu)其(qi)實就是一次轉(zhuan)場(chang)動畫所(suo)必備的六個元(yuan)素。它們可(ke)以分為兩(liang)組,前(qian)兩(liang)個參數(shu)為一組,表示頁面xian)奶zhuan)關系,後面四個為一組,表示動畫的執行xin)嘸 /p>

    這個方法的缺點(dian)之(zhi)一是可(ke)自定義(yi)程(cheng)度不高(在後面您會發現能自定義(yi)的不僅僅是動畫方式),另一個缺點(dian)則(ze)是重用性不好,也可(ke)以說是耦(ou)合度比較大。

    在最後兩(liang)個閉包參數(shu)中,可(ke)以預見的是fromViewController和toViewController參數(shu)都會被用到,而且他(ta)們是動畫的關鍵(jian)。假設視圖控(kong)制器A可(ke)以跳轉(zhuan)到B、C、D、E、F,而且跳轉(zhuan)動畫基(ji)本相似,您會發現transitionFromViewController方法要被復(fu)制多次,每次只會修改少量內容。

    同福彩票官网

    出于解耦(ou)和提高可(ke)自定義(yi)程(cheng)度的mu)悸lv),我們來學習轉(zhuan)場(chang)動畫的正確使用姿勢。

    首先要了si)庖桓齬?jian)概念︰轉(zhuan)場(chang)動畫代(dai)理,它是一個實現zhi)IViewControllerTransitioningDelegate協議的對象。我們qie)枰 約渮迪終飧齠韻螅 淖饔檬俏IKit提供以下幾個對象中的一個或多個︰

    Animator︰

    它是實現zhi)IViewControllerAnimatedTransitioning協議的對象,用于控(kong)制動畫的持(chi)續時間和動畫展示邏輯,代(dai)理可(ke)以為present和dismiss過程(cheng)分zhi)  nimator,也可(ke)以提供同一個Animator。

    交(jiao)互式Animator︰和Animator類似,不過它是交(jiao)互式的mo) 竺婊嵊邢 附檣/p>

    Presentation控(kong)制器︰

    它可(ke)以對present過程(cheng)更加徹底的自定義(yi),比如修改被展示視圖的大小,新(xin)增自定義(yi)視圖等,後面會有詳細介紹。


    轉(zhuan)場(chang)動畫代(dai)理

    在這一小節中,我們首先介紹最簡單的Animator。回顧一下轉(zhuan)場(chang)動畫必備的6個元(yuan)素,它們被huan)治 liang)組,彼此之(zhi)間沒有關聯。Animator的作用等同于第二組的四個元(yuan)素,也就是說對于同一個Animator,可(ke)以適用于A跳轉(zhuan)B,也可(ke)以適用于A跳轉(zhuan)C。它表示一種通用的頁面跳轉(zhuan)時的動畫邏輯,不受限于具體(ti)的視圖控(kong)制器。

    如果您讀懂了這段話,整(zheng)個自定義(yi)的轉(zhuan)場(chang)動畫邏輯就很清(qing)楚了,以視圖控(kong)制器A跳轉(zhuan)到B為例(li)︰

    創建動畫代(dai)理,在事lv)楸冉霞虻?保自己就可(ke)以作為代(dai)理設置B的transitioningDelegate為步驟1中創建的代(dai)理對象調(diao)用presentViewController:animated:completion:並(bing)把參數(shu)animated設置為true系統會找(zhao)到代(dai)理中提供的Animator,由Animator負責動畫邏輯

    用具體(ti)的例(li)子(zi)解釋就是︰

    // 這個類相當于Aclass CrossDissolveFirstViewController: UIViewController, UIViewControllerTransitioningDelegate { // 這個對象相當于B crossDissolveSecondViewController.transitioningDelegate = self // 點(dian)擊按鈕觸發的函(han)數(shu) func animationButtonDidClicked() { self.presentViewController(crossDissolveSecondViewController,    animated: true, completion: nil) } // 下面這兩(liang)個函(han)數(shu)定義(yi)在UIViewControllerTransitioningDelegate協議中 // 用于為present和dismiss提供animator func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) > UIViewControllerAnimatedTransitioning? {// 也可(ke)以使用CrossDissolveAnimator,動畫效果各有不同// return CrossDissolveAnimator() return HalfWaySpringAnimator() } func animationControllerForDismissedController(dismissed: UIViewController) > UIViewControllerAnimatedTransitioning? { return CrossDissolveAnimator() }}

    動畫的關鍵(jian)在于animator如何實現,它實現zhi)IViewControllerAnimatedTransitioning協議,至(zhi)少需(xu)要實現zhi)liang)個方法,我建議您仔(zi)細閱(yue)讀animateTransition方法中的注釋,它是整(zheng)個動畫邏輯的核心mo)/p>

    class HalfWaySpringAnimator: NSObject, UIViewControllerAnimatedTransitioning { /// 設置動畫的持(chi)續時間 func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) > NSTimeInterval { return 2 } /// 設置動畫的進行方式,附jie)邢 缸?停emo中其(qi)他(ta)地方的這個方法不再解釋 func animateTransition(transitionContext: UIViewControllerContextTransitioning) { let fromViewController = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey) let toViewController = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey) let containerView = transitionContext.containerView() // 需(xu)要關注一下from/to和presented/presenting的關系 // For a Presentation: // fromView = The presenting view. // toView = The presented view. // For a Dismissal: // fromView = The presented view. // toView = The presenting view. var fromView = fromViewController?.view var toView = toViewController?.view // iOS8引入了viewForKey方法,盡可(ke)能使用這個方法而不是直(zhi)接(jie)訪(fang)問controller的view屬(shu)性 // 比如在form sheet樣式中,我們為presentedViewController的view添(tian)加陰影或其(qi)他(ta)decoration,animator會對整(zheng)個decoration view // 添(tian)加動畫效果,而此時presentedViewController的view只是decoration view的一個子(zi)視圖 if transitionContext.respondsToSelector(Selector("viewForKey:")) {  fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)  toView = transitionContext.viewForKey(UITransitionContextToViewKey) } // 我們讓(rang)toview的origin.y在屏幕(mu)的一半處,這樣它從屏幕(mu)的中間位置彈起(qi)而不是從屏幕(mu)底部彈起(qi),彈起(qi)過程(cheng)中逐漸變為不透gai)toView?.frame = CGRectMake(fromView!.frame.origin.x, fromView!.frame.maxY / 2, fromView!.frame.width, fromView!.frame.height) toView?.alpha = 0.0 // 在present和,dismiss時,必須(xu)將toview添(tian)加到視圖層(ceng)次中 containerView?.addSubview(toView!) let transitionDuration = self.transitionDuration(transitionContext) // 使用spring動畫,有彈簧效果,動畫結束後一定要調(diao)用completeTransition方法 UIView.animateWithDuration(transitionDuration, delay: 0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0, options: .CurveLinear, animations: { () > Void in  toView!.alpha = 1.0 // 逐漸變為不透gai) toView?.frame = transitionContext.finalFrameForViewController(toViewController!) // 移動到指(zhi)定位置  }) { (finished: Bool) > Void in  let wasCancelled = transitionContext.transitionWasCancelled()  transitionContext.completeTransition(!wasCancelled) } }}

    animateTransition方法的核心則(ze)是從轉(zhuan)場(chang)動畫上下文(wen)獲(huo)取(qu)必要的信息以完成(cheng)動畫。上下文(wen)是一個實現zhi)IViewControllerContextTransitioning的對象,它的作用在于為animateTransition方法提供必備的信息。您不應該(gai)緩存(cun)任何關于動畫的信息,而是應該(gai)總是從轉(zhuan)場(chang)動畫上下文(wen)中獲(huo)取(qu)(比如fromView和toView),這樣可(ke)以保證(zheng)總是獲(huo)取(qu)到最新(xin)的、正確fan)男畔 /p>
    轉(zhuan)場(chang)動畫上下文(wen)

    獲(huo)取(qu)到足夠信息後,我們調(diao)用UIView.animateWithDuration方法把xun)  jiao)給Core Animation處理。千(qian)萬(wan)不要忘記在動畫調(diao)用結束後,執行completeTransition方法。

    本節的知識在Demo的Cross Dissolve文(wen)件夾中有詳細的代(dai)碼(ma)。其(qi)中有兩(liang)個animator文(wen)件,這說明我們可(ke)以為present和dismiss提供同一個animator,或者分zhi)  └髯遠雜Φnimator。如果兩(liang)者動畫效果類似,您可(ke)以共用同一個animator,惟一的區別(bie)在于︰

    present時,要把toView加入到container的視圖層(ceng)級(ji)。dismiss時,要把fromView從container的視圖層(ceng)級(ji)中移除。

    如果您被前(qian)面這一大段代(dai)碼(ma)和知識弄暈了,或者暫時用不到這些具體(ti)的知識,您至(zhi)少需(xu)要記住自定義(yi)動畫的mu)ji)本原(yuan)理和流程(cheng)︰

    設置將要跳轉(zhuan)到的視圖控(kong)制器(presentedViewController)的transitioningDelegate充當bei)dai)理的對象可(ke)以是源視圖控(kong)制器(presentingViewController),也可(ke)以是自己創建的對象,它需(xu)要為轉(zhuan)場(chang)動畫提供一個animator對象。animator對象的animateTransition是整(zheng)個動畫的核心邏輯。

    同福彩票官网

    剛剛我們說到,設置了toViewController的transitioningDelegate屬(shu)性並(bing)且present時,UIKit會從代(dai)理處獲(huo)取(qu)animator,其(qi)實這里還有一個細節︰UIKit還會調(diao)用代(dai)理的interactionControllerForPresentation:方法來獲(huo)取(qu)交(jiao)互式控(kong)制器,如果得到了nil則(ze)執行非(fei)交(jiao)互式動畫,這就回到了上一節的na)諶蕁/p>

    如果獲(huo)取(qu)到了不是nil的對象,那麼UIKit不會調(diao)用animator的animateTransition方法,而是調(diao)用交(jiao)互式控(kong)制器(還記得前(qian)面介紹動畫代(dai)理的示意圖麼,交(jiao)互式動畫控(kong)制器和animator是平級(ji)關系)的startInteractiveTransition:方法。

    所(suo)謂的交(jiao)互式動畫,通常是基(ji)于手勢驅動,產生一個動畫完成(cheng)的百(bai)分zhi)壤純kong)制動畫效果(文(wen)章開頭fan)if中第二個動畫效果)。整(zheng)個動畫不再是一次性、連貫的完成(cheng),而是在任何時候都可(ke)以改變百(bai)分zhi)壬shen)至(zhi)取(qu)消。這需(xu)要一個實現zhi)IPercentDrivenInteractiveTransition協議的交(jiao)互式動畫控(kong)制器和animator協同工作。這看上去(qu)是一個非(fei)qian)8fu)雜的任務,但UIKit已經封(feng)裝了足夠多細節,我們只需(xu)要在交(jiao)互式動畫控(kong)制器和中定義(yi)一個時間處理函(han)數(shu)(比如處理滑動手勢),然後在接(jie)收到新(xin)的事件時,計算動畫完成(cheng)的百(bai)分zhi)炔bing)且調(diao)用updateInteractiveTransition來更新(xin)動畫進度即可(ke)。

    用下面這段代(dai)碼(ma)簡單表示一下整(zheng)個流程(cheng)(刪(shan)除了部分細節和注釋,請不要以此為正確參考),完整(zheng)的代(dai)碼(ma)請參考demo中的Interactivity文(wen)件夾︰

    // 這個相當于fromViewControllerclass InteractivityFirstViewController: UIViewController { // 這個相當于toViewController lazy var interactivitySecondViewController: InteractivitySecondViewController = InteractivitySecondViewController() // 定義(yi)了一個InteractivityTransitionDelegate類作為代(dai)理 lazy var customTransitionDelegate: InteractivityTransitionDelegate = InteractivityTransitionDelegate() override func viewDidLoad() { super.viewDidLoad() setupView() // 主(zhu)要是一些UI控(kong)件的布局,可(ke)以無(wu)視其(qi)實現細節 /// 設置動畫代(dai)理,這個代(dai)理比較復(fu)雜,所(suo)以我們qie)xin)建了一個代(dai)理對象而不是讓(rang)self作為代(dai)理 interactivitySecondViewController.transitioningDelegate = customTransitionDelegate } // 觸發手勢時,也會調(diao)用animationButtonDidClicked方法 func interactiveTransitionRecognizerAction(sender: UIScreenEdgePanGestureRecognizer) { if sender.state == .Began {  self.animationButtonDidClicked(sender) } } func animationButtonDidClicked(sender: AnyObject) { self.presentViewController(interactivitySecondViewController, animated: true, completion: nil) }}

    非(fei)交(jiao)互式的動畫代(dai)理只需(xu)要為present和dismiss提供animator即可(ke),但是在交(jiao)互式的動畫代(dai)理中,還需(xu)要為present和dismiss提供交(jiao)互式動畫控(kong)制器︰

    class InteractivityTransitionDelegate: NSObject, UIViewControllerTransitioningDelegate { func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) > UIViewControllerAnimatedTransitioning? { return InteractivityTransitionAnimator(targetEdge: targetEdge) } func animationControllerForDismissedController(dismissed: UIViewController) > UIViewControllerAnimatedTransitioning? { return InteractivityTransitionAnimator(targetEdge: targetEdge) } /// 前(qian)兩(liang)個函(han)數(shu)和淡入淡出demo中的實現一致 /// 後兩(liang)個函(han)數(shu)用于實現交(jiao)互式動畫 func interactionControllerForPresentation(animator: UIViewControllerAnimatedTransitioning) > UIViewControllerInteractiveTransitioning? { return TransitionInteractionController(gestureRecognizer: gestureRecognizer, edgeForDragging: targetEdge) } func interactionControllerForDismissal(animator: UIViewControllerAnimatedTransitioning) > UIViewControllerInteractiveTransitioning? { return TransitionInteractionController(gestureRecognizer: gestureRecognizer, edgeForDragging: targetEdge) }}

    animator中的代(dai)碼(ma)略去(qu),它和非(fei)交(jiao)互式動畫中的animator類似。因為交(jiao)互式的動畫只是一種錦上添(tian)花,它必須(xu)支持(chi)非(fei)交(jiao)互式的動畫,比如這個例(li)子(zi)中,點(dian)擊按鈕依然出發的是非(fei)交(jiao)互式的動畫,只是手勢滑動才會觸發交(jiao)互式動畫。

    class TransitionInteractionController: UIPercentDrivenInteractiveTransition { /// 當手勢有滑動時bei)? 飧齪han)數(shu) func gestureRecognizeDidUpdate(gestureRecognizer: UIScreenEdgePanGestureRecognizer) { switch gestureRecognizer.state { case .Began: break case .Changed: self.updateInteractiveTransition(self.percentForGesture(gestureRecognizer)) //手勢滑動,更新(xin)百(bai)分zhi)case .Ended: // 滑動結束,判斷是否超過一半,如果是則(ze)完成(cheng)剩(sheng)下的動畫,否則(ze)取(qu)消動畫  if self.percentForGesture(gestureRecognizer) >= 0.5 {  self.finishInteractiveTransition()  }  else {  self.cancelInteractiveTransition()  } default: self.cancelInteractiveTransition() } } private func percentForGesture(gesture: UIScreenEdgePanGestureRecognizer) > CGFloat { let percent = 根據gesture計算得出 return percent }}

    交(jiao)互式動畫是在非(fei)交(jiao)互式動畫的mu)ji)礎上實現的mo) 頤切(qie)枰 唇ㄒ桓黽壇凶IPercentDrivenInteractiveTransition類型的子(zi)類,並(bing)且在動畫代(dai)理中返(fan)回這個類型的實例(li)對象。

    在這個類型中,監听手勢(或者下載進度等等)的時間變化,然後調(diao)用percentForGesture方法更新(xin)動畫進度即可(ke)。

    同福彩票官网

    在進行轉(zhuan)場(chang)動畫的同時,您還可(ke)以進行一些同步的mo) e)外的動畫,比如文(wen)章開頭gif中的第三個例(li)子(zi)。presentedView和presentingView可(ke)以更改自身(shen)的視圖層(ceng)級(ji),添(tian)加額(e)外的效果(陰影,圓角)。UIKit使用轉(zhuan)成(cheng)協調(diao)器來管理這些額(e)外的動畫。您可(ke)以通過需(xu)要產生動畫效果的視圖控(kong)制器的transitionCoordinator屬(shu)性來獲(huo)取(qu)轉(zhuan)場(chang)協調(diao)器,轉(zhuan)場(chang)協調(diao)器只在轉(zhuan)場(chang)動畫的執行過程(cheng)中存(cun)在。


    轉(zhuan)場(chang)動畫協調(diao)器

    想要完成(cheng)gif中第三個例(li)子(zi)的效果,我們還需(xu)要使用UIModalPresentationStyle.Custom來代(dai)替(ti).FullScreen。因為後者會移除fromViewController,這顯然不huan)閑xu)求(qiu)。

    當present的方式為.Custom時,我們還可(ke)以使用UIPresentationController更加徹底的mu)?譜zhuan)場(chang)動畫的效果。一個 presentation controller具備以下幾個功能︰

    設置presentedViewController的視圖大小添(tian)加自定義(yi)視圖來改變presentedView的外觀為任何自定義(yi)的視圖提供轉(zhuan)場(chang)動畫效果根據size class進行響(xiang)應式布局

    您可(ke)以認為,. FullScreen以及其(qi)他(ta)present風格都是swift為我們實現提供好的mo) 鞘Custom的特例(li)。而.Custom允許(xu)我們更加自由的定義(yi)轉(zhuan)場(chang)動畫效果。

    UIPresentationController提供了四個函(han)數(shu)來定義(yi)present和dismiss動畫開始前(qian)後的操作︰

    presentationTransitionWillBegin: present將要執行時presentationTransitionDidEnd︰present執行結束後dismissalTransitionWillBegin︰dismiss將要執行時dismissalTransitionDidEnd︰dismiss執行結束後

    下面xian)拇dai)碼(ma)簡要描述(shu)了gif中第三個動畫效果的實現原(yuan)理,您可(ke)以在demo的Custom Presentation文(wen)件夾下查看完成(cheng)代(dai)碼(ma)︰

    // 這個相當于fromViewControllerclass CustomPresentationFirstViewController: UIViewController { // 這個相當于toViewController lazy var customPresentationSecondViewController: CustomPresentationSecondViewController = CustomPresentationSecondViewController() // 創建PresentationController lazy var customPresentationController: CustomPresentationController = CustomPresentationController(presentedViewController: self.customPresentationSecondViewController, presentingViewController: self) override func viewDidLoad() { super.viewDidLoad() setupView() // 主(zhu)要是一些UI控(kong)件的布局,可(ke)以無(wu)視其(qi)實現細節 // 設置轉(zhuan)場(chang)動畫代(dai)理 customPresentationSecondViewController.transitioningDelegate = customPresentationController } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } func animationButtonDidClicked() { self.presentViewController(customPresentationSecondViewController, animated: true, completion: nil) }}

    重點(dian)在于如何實現CustomPresentationController這個類︰

    class CustomPresentationController: UIPresentationController, UIViewControllerTransitioningDelegate { var presentationWrappingView: UIView? // 這個視圖封(feng)裝了原(yuan)視圖,添(tian)加了陰影和圓角qie)?var dimmingView: UIView? = nil // alpha為0.5的黑色蒙(meng)版 // 告訴UIKit為哪(na)個視圖添(tian)加動畫效果 override func presentedView() > UIView? { return self.presentationWrappingView }}// 四個方法自定義(yi)轉(zhuan)場(chang)動畫發生前(qian)後的操作extension CustomPresentationController { override func presentationTransitionWillBegin() { // 設置presentationWrappingView和dimmingView的UI效果 let transitionCoordinator = self.presentingViewController.transitionCoordinator() self.dimmingView?.alpha = 0 // 通過轉(zhuan)場(chang)協調(diao)器執行同步的動畫效果 transitionCoordinator?.animateAlongsideTransition({ (context: UIViewControllerTransitionCoordinatorContext) > Void in  self.dimmingView?.alpha = 0.5  }, completion: nil) } /// present結束時,把dimmingView和wrappingView都清(qing)空(kong),這些臨(lin)時視圖用不到了 override func presentationTransitionDidEnd(completed: Bool) { if !completed {  self.presentationWrappingView = nil  self.dimmingView = nil } } /// dismiss開始時,讓(rang)dimmingView完全透gai)鰨 飧齠  nimator中的動畫同時發生 override func dismissalTransitionWillBegin() { let transitionCoordinator = self.presentingViewController.transitionCoordinator() transitionCoordinator?.animateAlongsideTransition({ (context: UIViewControllerTransitionCoordinatorContext) > Void in  self.dimmingView?.alpha = 0  }, completion: nil) } /// dismiss結束時,把dimmingView和wrappingView都清(qing)空(kong),這些臨(lin)時視圖用不到了 override func dismissalTransitionDidEnd(completed: Bool) { if completed {  self.presentationWrappingView = nil  self.dimmingView = nil } }}extension CustomPresentationController {}

    除此以外,這個類還要處理子(zi)視圖布局相關的邏輯。它作為動畫代(dai)理,還需(xu)要為動畫提供animator對象,詳細fu)ma)請在demo的Custom Presentation文(wen)件夾下閱(yue)讀。

    同福彩票官网

    到目(mu)前(qian)為止,所(suo)有轉(zhuan)場(chang)動畫都是適用于present和dismiss的mo) qi)實UINavigationController也可(ke)以自定義(yi)轉(zhuan)場(chang)動畫。兩(liang)者是平行關系,很多都可(ke)以類比過來︰

    class FromViewController: UIViewController, UINavigationControllerDelegate { let toViewController: ToViewController = ToViewController() override func viewDidLoad() { super.viewDidLoad() setupView() // 主(zhu)要是一些UI控(kong)件的布局,可(ke)以無(wu)視其(qi)實現細節 self.navigationController.delegate = self }}

    與present/dismiss不同的時,現在視圖控(kong)制器實現的是UINavigationControllerDelegate協議,讓(rang)自己成(cheng)為navigationController的代(dai)理。這個協議類似于此前(qian)的UIViewControllerTransitioningDelegate協議。

    FromViewController實現UINavigationControllerDelegate協議的具體(ti)操作如下︰

    func navigationController(navigationController: UINavigationController, animationControllerForOperation operation: UINavigationControllerOperation,   fromViewController fromVC: UIViewController,    toViewController toVC: UIViewController)    > UIViewControllerAnimatedTransitioning? { if operation == .Push {  return PushAnimator() } if operation == .Pop {  return PopAnimator() } return nil; }

    至(zhi)于animator,就和此前(qian)沒有任何區別(bie)了。可(ke)見,一個封(feng)裝得很好的animator,不僅能在present/dismiss時使用,甚(shen)至(zhi)還可(ke)以在push/pop時使用。

    UINavigationController也可(ke)以添(tian)加交(jiao)互式轉(zhuan)場(chang)動畫,原(yuan)理也和此前(qian)類似。

    同福彩票官网

    對于非(fei)交(jiao)互式動畫,需(xu)要設置presentedViewController的transitioningDelegate屬(shu)性,這個代(dai)理需(xu)要為present和dismiss提供animator。在animator中規定了動畫的持(chi)續時間和表現邏輯。

    對于交(jiao)互式動畫,需(xu)要在此前(qian)的mu)ji)礎上,由transitioningDelegate屬(shu)性提供交(jiao)互式動畫控(kong)制器。在控(kong)制器中進行事件處理,然後更新(xin)動畫完成(cheng)進度qu)/p>

    對于自定義(yi)動畫,可(ke)以通過UIPresentationController中的四個函(han)數(shu)自定義(yi)動畫執行前(qian)後的效果,可(ke)以修改presentedViewController的大小、外觀並(bing)同步執行其(qi)他(ta)的動畫。

About IT165 -廣(guang)告服務 -隱(yin)私(si)聲明 -版權(quan)申(shen)明 -免責條款 -網站地圖 -網友投稿 -聯系方式
本站內容來自于互聯網,僅供用于網絡(luo)技(ji)術學習,學習中請遵循相關法律法規
同福彩票官网 | 下一页