UIView Animations 學習筆記(二)定製動畫效果及切換效果

目錄

2、視圖切換定製

2.1 基礎說明

要建立定製切換效果,你須要作以下的事情:html

  1. 建立一個類來實現UIViewControllerAnimatedTransitioning協議。在這個類中將編寫代碼來執行動畫,這個類將做爲動畫控制器被關聯。
  2. 在呈現一個視圖控制器以前,設置一個類做爲它的切換效果委託。這個委託將爲動畫控制器獲取一個回調方法,這個回調方法用於視圖控制器的呈現。
  3. 實現回調方法來返回一個在第一步建立的動畫控制器的實例。

2.1.1 UIViewControllerAnimatedTransitioning協議

UIViewControllerAnimatedTransitioning協議用於描述視圖控制器切換的動畫效果,咱們能夠經過實現這個協議,並利用該類來實如今視圖間切換過程當中的動畫效果。能夠在這個類中定義一個動畫對象,這個動畫對象建立一個視圖控制器在一個固定的時間內出現/消失在屏幕上的動畫效果。使用這個協議建立的動畫 必須 是沒法交互的。若是要建立能夠交互的切換,必須混合動畫對象和另外一個控制動畫時間的對象。ios

在動畫對象中,實現transitionDuration:方法來指定切換的過程,實現animateTransition:方法來建立動畫。在切換過程當中使用的對象的信息在一個上下文對象中傳遞給animateTransition:方法。使用這個上下文對象(UIViewControllerContextTransitioning)提供的信息,來移動目標視圖控制器的視圖在指定的區間內出現/消失在屏幕上。swift

從一個實現了UIViewControllerTransitioningDelegate協議的切換委託對象中建立一個動畫對象。當呈現一個視圖控制器時,設置呈現類型爲UIModalPresentationCustom,並指定切換委託到視圖控制器的transitioningDelegate屬性。視圖控制器從切換委託中接受動畫對象,並使用這個切換委託來執行動畫。能夠爲視圖控制器的出現、消失分別定製不一樣的動畫對象。app

爲了添加用戶交互到一個視圖控制器的切換效果中,必須一塊兒使用一個動畫對象和一個交互動畫對象(一個實現UIViewControllerInteractiveTransitioning協議的定製類)。ide

執行切換學習

切換過程:動畫

具體實現以下所示。ui

import Foundation
import UIKit

class AnimatedTransitioning: NSObject, UIViewControllerAnimatedTransitioning {

    func transitionDuration(transitionContext: UIViewControllerContextTransitioning) -> NSTimeInterval {
        return 5
    }
    
    func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
        let fromViewController = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)!
        let toViewController = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)!
        
        let finalFrameForVC = transitionContext.finalFrameForViewController(toViewController)
        
        let containerView = transitionContext.containerView()
        let bounds = UIScreen.mainScreen().bounds
        
        toViewController.view.frame = CGRectOffset(finalFrameForVC, 0, bounds.size.height)
        containerView.addSubview(toViewController.view)
        
        UIView.animateWithDuration(transitionDuration(transitionContext), delay: 0.0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.0, options: .CurveLinear, animations: {
            fromViewController.view.alpha = 0.5
            toViewController.view.frame = finalFrameForVC
            }, completion: {
                finished in
                transitionContext.completeTransition(true)
                fromViewController.view.alpha = 1.0
        })
    }
}

2.1.2 UIViewControllerTransitioningDelegate

import UIKit

class ViewController: UIViewController, UIViewControllerTransitioningDelegate {

    // ...

    let customPresentAnimationController = CustomPresentAnimationController()
    let customDismissAnimationController = CustomDismissAnimationController()

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        
        if segue.identifier == "showAction" {
            let toViewController = segue.destinationViewController as! UIViewController

            // 用於給目標視圖指定切換動畫代理
            toViewController.transitioningDelegate = self
        }
    }

    // 用於視圖出現
    func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return customPresentAnimationController
    }
    
    // 用於視圖消失
    func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return customDismissAnimationController
    }

    // ...
}

2.1.3 UIViewControllerInteractiveTransitioning

注意:.net

UIPercentDrivenInteractiveTransitionUIViewControllerInteractiveTransitioning的子類代理

import UIKit

class CustomInteractionController: UIPercentDrivenInteractiveTransition {
    
    var navigationController: UINavigationController!
    var shouldCompleteTransition = false
    var transitionInProgress = false
    
    var completionSeed: CGFloat {
        return 1 - percentComplete
    }
    
    func attachToViewController(viewController: UIViewController) {
        navigationController = viewController.navigationController
        setupGestureRecognizer(viewController.view)
    }
    
    private func setupGestureRecognizer(view: UIView) {
        view.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: "handlePanGesture:"))
    }
    
    func handlePanGesture(gestureRecognizer: UIPanGestureRecognizer) {
        let viewTranslation = gestureRecognizer.translationInView(gestureRecognizer.view!.superview!)
        switch gestureRecognizer.state {
        case .Began:
            transitionInProgress = true
            navigationController.popViewControllerAnimated(true)
        case .Changed:
            var const = CGFloat(fminf(fmaxf(Float(viewTranslation.x / 200.0), 0.0), 1.0))
            shouldCompleteTransition = const > 0.5
            updateInteractiveTransition(const)
        case .Cancelled, .Ended:
            transitionInProgress = false
            if !shouldCompleteTransition || gestureRecognizer.state == .Cancelled {
                cancelInteractiveTransition()
            } else {
                finishInteractiveTransition()
            }
        default:
            println("Swift switch must be exhaustive, thus the default")
        }
    }
}

2.1.4 UIViewControllerContextTransitioning

UIViewControllerContextTransitioning協議的方法爲切換的兩個視圖控制器提供上下文信息。在一次切換當中,切換中使用的動畫對象從UIKit接受一個完整的配置上下文對象,UIViewControllerAnimatorTransitioningUIViewControllerInteractiveTransitioning協議的方法從提供的對象中提取它們須要的信息。

訪問切換對象

獲取切換框體矩形

finalFrameForViewController用於獲取指定的視圖控制器視圖最終的框體矩形。

獲取切換行爲

反饋切換進度

獲取屏幕方向

常量

View Controller Transition Keys用於標識在切換執行過程當中所存在的視圖控制器,包含兩個值,一個是UITransitionContextFromViewControllerKey用於標識在動畫開始時就已經存在的視圖控制器,一個是UITransitionContextToViewControllerKey用於標識在動畫完成後應該存在的視圖控制器。

View Transition Keys用於標識在切換執行過程當中所存在的視圖,包含兩個值,一個是UITransitionContextFromViewKey用於標識在動畫開始時就已經存在的視圖,一個是UITransitionContextToViewKey用於標識在動畫完成後應該存在的視圖。

相關文章
相關標籤/搜索