前言
在開發中,無論我們使用 Push 還是 Present 推出新的 ViewController 時,系統為了提高用戶體驗都會為我們默認加上一些過渡動畫。但是,系統默認的動畫總是不能滿足大家各種各樣的需求的,所以系統也為我們提供了在不同場景下自定義過渡動畫以及通過手勢控制過渡進度的實現方案。
這篇文章記錄了自定義轉場動畫中的幾種情況:
效果圖
預備
首先,我們現在介紹幾個在自定義轉場動畫時需要接觸的協議:
我們在定義好了實現上面兩個協議的類后,只需要在需要進行轉場的地方,提供對應的對象即可。
ps:下面的實例中,請大家忽略動畫效果,關注實現。(其實是懶得去寫太多動畫了。🤦♂️)
模態跳轉(Present)
場景
self.present(vc!, animated: true) {} self.dismiss(animated: true) {}
實現步驟
需要實現的UIViewControllerTransitioningDelegate方法:
//返回用于 present 的自定義 transition 動畫optional func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? //返回用于 dismiss 的自定義 transition 動畫optional func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning?
實例
/// 第一個 VC 中點擊跳轉func presentClick(_ sender: Any) { let vc = self.storyboard?.instantiateViewController(withIdentifier: "PresentSecondViewController") vc?.modalPresentationStyle = .fullScreen vc?.transitioningDelegate = self self.present(vc!, animated: true) {}}// 第一個 VC 實現協議,返回控制轉場動畫效果的實例extension PresentFirstViewController: UIViewControllerTransitioningDelegate { func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { return NormalPresentAnimator() } func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { return NormalPresentAnimator() }}
導航控制器跳轉(Push)
場景
self.navigationController?.pushViewController(vc!, animated: true)self.navigationController?.popViewController(animated: true)
實現步驟
需要實現的UINavigationControllerDelegate方法:
optional func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationController.Operation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning?
實例
class PushFirstViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() self.navigationController?.delegate = self } @IBAction func pushClick(_ sender: Any) { let vc = self.storyboard?.instantiateViewController(withIdentifier: "PushSecondViewController") self.navigationController?.pushViewController(vc!, animated: true) }}extension PushFirstViewController: UINavigationControllerDelegate { //返回自定義過渡動畫 func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationController.Operation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? { if operation == .pop && fromVC is PushFirstViewController { return nil } return NormalPushAnimator() }}
UITabbarController
在前面的兩個專場實現中,我們在需要轉場的類中分別實現了UIViewControllerTransitioningDelegate 及 UINavigationControllerDelegate 方法,在這兩個協議中,還有這樣幾個方法:
/// UIViewControllerTransitioningDelegateoptional func interactionControllerForPresentation(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning?optional func interactionControllerForDismissal(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning?/// UINavigationControllerDelegateoptional func navigationController(_ navigationController: UINavigationController, interactionControllerFor animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning?
上面這幾個方法呢?其實就是我們通過利用手勢轉場時過渡的進度處理方法。我們需要在代理方法中返回一個實現了 UIViewControllerInteractiveTransitioning 協議的對象來對轉場進度進行控制。下面的 UITabbarController 中我就實現一個利用手勢控制轉場的例子。 Present 及 Push/Pop 按照相同的思路實現即可。
場景
UITabbarController 在默認的狀態下,切換控制器時是沒有動畫效果的。如果需要動畫效果的話,需要我們進行自定義。
實現步驟
/// 返回實現了 UIViewControllerAnimatedTransitioning 協議的實例func tabBarController(_ tabBarController: UITabBarController, animationControllerForTransitionFrom fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning?/// 返回實現了 UIViewControllerInteractiveTransitioning 協議的實例 func tabBarController(_ tabBarController: UITabBarController, interactionControllerFor animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning?
實例
class TabbarController: UITabBarController, UITabBarControllerDelegate { override func viewDidLoad() { super.viewDidLoad() self.delegate = self}func tabBarController(_ tabBarController: UITabBarController, animationControllerForTransitionFrom fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? { if self.selectedIndex == 0 { return TabbarAnimator(edge: .right) } else { return TabbarAnimator(edge: .left) }} func tabBarController(_ tabBarController: UITabBarController, interactionControllerFor animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? { if self.panGesture.state == .began || self.panGesture.state == .changed { return TabbarInteractionTransition(pan: self.panGesture) } else { return nil }}
三方框架――Lottie
介紹
Lottie 是 Android 和 iOS 的移動庫,用 bodymovin 解析 Adobe After Effects 導出為 json 的動畫并在移動設備上生成矢量動畫。設計師可以輕松的創建漂亮(復雜)的動畫,無需程序員辛苦地手動去創建及調試。
場景
實現一些特殊的轉場,且程序員無足夠時間調試動畫時。
實現步驟
ps:Lottie 轉場的 LOTAnimationTransitionController 在 3.0.0 版本后被移除,所以需要使用 Lottie 做轉場時,需要在導入時,指定版本號為更早的版本。我這里使用的是 2.5.3。
實例
/// 第一個 VCfunc presentClick(_ sender: Any) { let vc = self.storyboard?.instantiateViewController(withIdentifier: "LottieSecondViewController") vc?.transitioningDelegate = self self.present(vc!, animated: true) {}}/// 實現 UIViewControllerTransitioningDelegate,返回 LOTAnimationTransitionController 的實例extension LottieFirstViewController: UIViewControllerTransitioningDelegate { func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { let transitionController = LOTAnimationTransitionController(animationNamed: "Count", fromLayerNamed: "", toLayerNamed: "", applyAnimationTransform: false) return transitionController } func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { let transitionController = LOTAnimationTransitionController(animationNamed: "Three", fromLayerNamed: "", toLayerNamed: "", applyAnimationTransform: false) return transitionController }}
總結
上面的所有動畫的示例可以在我的Github上找到哦,各位前快去下載把玩吧。
好的轉場動畫,在用戶交互上會帶來更加美妙的體驗。讓用戶盡享絲滑哦。
好了,以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對武林網的支持。
新聞熱點
疑難解答