1. 程式人生 > >控制器自定義動畫跳轉 [導航跳轉]

控制器自定義動畫跳轉 [導航跳轉]

參考資料:

圖例:

跳轉的動畫有很多,全部可以自定義

這裡寫圖片描述

建立自定義轉換你必須遵循三個步驟:

  • 1、建立一個類,並實現了 UIViewControllerAnimatedTransitioning 協議
  • 2、建立一個類作為 UINavigationControllerDelegate 過渡代理,實現對應方法
  • 3、在將要 push 的控制器內設定導航控制器的代理為自定義的代理(步驟2的代理類)

核心程式碼

1、建立一個類,並實現了 UIViewControllerAnimatedTransitioning 協議

class CustomNaviAnimatedTransition: NSObject {
    var isPushed: Bool?

    // 通過 static let 建立單例
    static let shared = CustomNaviAnimatedTransition()
    // 建構函式,init前加private修飾,表示原始構造方法只能自己使用,外界不發呼叫
    private override init() { }
}

/// 從左往右進,從左往右出
extension CustomNaviAnimatedTransition: UIViewControllerAnimatedTransitioning {

    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.5
} func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { let fromView = transitionContext.view(forKey: .from)! let toView = transitionContext.view(forKey: .to)! let containerView = transitionContext.containerView if isPushed == true { containerView.addSubview
(toView) toView.frame.origin.x = -toView.bounds.width UIView.animate(withDuration: 0.3, animations: { toView.frame.origin.x = 0 }, completion: { (finished) in if finished { transitionContext.completeTransition(finished) } }) } else { containerView.insertSubview
(toView, belowSubview: fromView) UIView.animate(withDuration: 0.3, animations: { fromView.frame.origin.x = fromView.frame.width }, completion: { (finished) in if finished { transitionContext.completeTransition(finished) } }) } } }

2、建立一個類作為 UINavigationControllerDelegate 過渡代理,實現對應方法

class CustomNaviAnimateDelagete: NSObject, UINavigationControllerDelegate {

    func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationControllerOperation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        let animationTransition = CustomNaviAnimatedTransition.shared
        animationTransition.isPushed = operation.rawValue == 1
        return animationTransition
    }
}

3、在將要 push 的控制器內設定導航控制器的代理為自定義的代理(步驟2的代理類)

注意:代理不能為區域性變數

class ViewController: UIViewController {

    var cnaDelegate = CustomNaviAnimateDelagete()

    override func viewDidLoad() {
        super.viewDidLoad()

        self.navigationController?.delegate = cnaDelegate
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        let vc = TempViewController()
        navigationController?.pushViewController(vc, animated: true)
    }
}