iOS自定義轉(zhuǎn)場(chǎng)動(dòng)畫的幾種情況
前言
在開(kāi)發(fā)中,無(wú)論我們使用 Push 還是 Present 推出新的 ViewController 時(shí),系統(tǒng)為了提高用戶體驗(yàn)都會(huì)為我們默認(rèn)加上一些過(guò)渡動(dòng)畫。但是,系統(tǒng)默認(rèn)的動(dòng)畫總是不能滿足大家各種各樣的需求的,所以系統(tǒng)也為我們提供了在不同場(chǎng)景下自定義過(guò)渡動(dòng)畫以及通過(guò)手勢(shì)控制過(guò)渡進(jìn)度的實(shí)現(xiàn)方案。
這篇文章記錄了自定義轉(zhuǎn)場(chǎng)動(dòng)畫中的幾種情況:
- 模態(tài)跳轉(zhuǎn)(Present)
- 導(dǎo)航控制器跳轉(zhuǎn)(Push)
- UITabbarController
- 三方框架——Lottie
效果圖

預(yù)備
首先,我們現(xiàn)在介紹幾個(gè)在自定義轉(zhuǎn)場(chǎng)動(dòng)畫時(shí)需要接觸的協(xié)議:
- UIViewControllerAnimatedTransitioning: 實(shí)現(xiàn)此協(xié)議的實(shí)例控制轉(zhuǎn)場(chǎng)動(dòng)畫效果。
- UIViewControllerInteractiveTransitioning: 實(shí)現(xiàn)此協(xié)議的實(shí)例控制著利用手勢(shì)過(guò)渡時(shí)的進(jìn)度處理。
我們?cè)诙x好了實(shí)現(xiàn)上面兩個(gè)協(xié)議的類后,只需要在需要進(jìn)行轉(zhuǎn)場(chǎng)的地方,提供對(duì)應(yīng)的對(duì)象即可。
ps:下面的實(shí)例中,請(qǐng)大家忽略動(dòng)畫效果,關(guān)注實(shí)現(xiàn)。(其實(shí)是懶得去寫太多動(dòng)畫了。🤦♂️)
模態(tài)跳轉(zhuǎn)(Present)
場(chǎng)景
self.present(vc!, animated: true) {}
self.dismiss(animated: true) {}
實(shí)現(xiàn)步驟
- 設(shè)置將要 present 的 ViewController 的 transitioningDelegate 對(duì)象,此對(duì)象是實(shí)現(xiàn)協(xié)議 UIViewControllerTransitioningDelegate 的實(shí)例。
- 實(shí)現(xiàn) UIViewControllerTransitioningDelegate 協(xié)議中的幾個(gè)代理方法,返回實(shí)現(xiàn)了 UIViewControllerAnimatedTransitioning 協(xié)議的動(dòng)畫效果控制類。
需要實(shí)現(xiàn)的UIViewControllerTransitioningDelegate方法:
//返回用于 present 的自定義 transition 動(dòng)畫 optional func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? //返回用于 dismiss 的自定義 transition 動(dòng)畫 optional func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning?
實(shí)例
/// 第一個(gè) VC 中點(diǎn)擊跳轉(zhuǎn)
func presentClick(_ sender: Any) {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "PresentSecondViewController")
vc?.modalPresentationStyle = .fullScreen
vc?.transitioningDelegate = self
self.present(vc!, animated: true) {}
}
// 第一個(gè) VC 實(shí)現(xiàn)協(xié)議,返回控制轉(zhuǎn)場(chǎng)動(dòng)畫效果的實(shí)例
extension PresentFirstViewController: UIViewControllerTransitioningDelegate {
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return NormalPresentAnimator()
}
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return NormalPresentAnimator()
}
}
導(dǎo)航控制器跳轉(zhuǎn)(Push)
場(chǎng)景
self.navigationController?.pushViewController(vc!, animated: true) self.navigationController?.popViewController(animated: true)
實(shí)現(xiàn)步驟
- 設(shè)置導(dǎo)航控制器 UINavigationController 的 delegate。
- 實(shí)現(xiàn) UINavigationControllerDelegate 協(xié)議中的代理方法,返回實(shí)現(xiàn)了 UIViewControllerAnimatedTransitioning 協(xié)議的動(dòng)畫效果控制類。
需要實(shí)現(xiàn)的UINavigationControllerDelegate方法:
optional func navigationController(_ navigationController: UINavigationController,
animationControllerFor operation: UINavigationController.Operation,
from fromVC: UIViewController,
to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning?
實(shí)例
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 {
//返回自定義過(guò)渡動(dòng)畫
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
在前面的兩個(gè)專場(chǎng)實(shí)現(xiàn)中,我們?cè)谛枰D(zhuǎn)場(chǎng)的類中分別實(shí)現(xiàn)了UIViewControllerTransitioningDelegate 及 UINavigationControllerDelegate 方法,在這兩個(gè)協(xié)議中,還有這樣幾個(gè)方法:
/// UIViewControllerTransitioningDelegate
optional func interactionControllerForPresentation(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning?
optional func interactionControllerForDismissal(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning?
/// UINavigationControllerDelegate
optional func navigationController(_ navigationController: UINavigationController,
interactionControllerFor animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning?
上面這幾個(gè)方法呢?其實(shí)就是我們通過(guò)利用手勢(shì)轉(zhuǎn)場(chǎng)時(shí)過(guò)渡的進(jìn)度處理方法。我們需要在代理方法中返回一個(gè)實(shí)現(xiàn)了 UIViewControllerInteractiveTransitioning 協(xié)議的對(duì)象來(lái)對(duì)轉(zhuǎn)場(chǎng)進(jìn)度進(jìn)行控制。下面的 UITabbarController 中我就實(shí)現(xiàn)一個(gè)利用手勢(shì)控制轉(zhuǎn)場(chǎng)的例子。 Present 及 Push/Pop 按照相同的思路實(shí)現(xiàn)即可。
場(chǎng)景
UITabbarController 在默認(rèn)的狀態(tài)下,切換控制器時(shí)是沒(méi)有動(dòng)畫效果的。如果需要?jiǎng)赢嬓Ч脑?,需要我們進(jìn)行自定義。
實(shí)現(xiàn)步驟
- 設(shè)置 UITabbarController 的 delegate。
- 實(shí)現(xiàn) UITabBarControllerDelegate 協(xié)議中的代理方法,返回實(shí)現(xiàn)了 UIViewControllerAnimatedTransitioning 協(xié)議的動(dòng)畫效果控制類,以及返回實(shí)現(xiàn)了 UIViewControllerInteractiveTransitioning 協(xié)議的轉(zhuǎn)場(chǎng)進(jìn)度控制類。
/// 返回實(shí)現(xiàn)了 UIViewControllerAnimatedTransitioning 協(xié)議的實(shí)例
func tabBarController(_ tabBarController: UITabBarController,
animationControllerForTransitionFrom fromVC: UIViewController,
to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning?
/// 返回實(shí)現(xiàn)了 UIViewControllerInteractiveTransitioning 協(xié)議的實(shí)例
func tabBarController(_ tabBarController: UITabBarController,
interactionControllerFor animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning?
實(shí)例
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 的移動(dòng)庫(kù),用 bodymovin 解析 Adobe After Effects 導(dǎo)出為 json 的動(dòng)畫并在移動(dòng)設(shè)備上生成矢量動(dòng)畫。設(shè)計(jì)師可以輕松的創(chuàng)建漂亮(復(fù)雜)的動(dòng)畫,無(wú)需程序員辛苦地手動(dòng)去創(chuàng)建及調(diào)試。
場(chǎng)景
實(shí)現(xiàn)一些特殊的轉(zhuǎn)場(chǎng),且程序員無(wú)足夠時(shí)間調(diào)試動(dòng)畫時(shí)。
實(shí)現(xiàn)步驟
- 在工程中導(dǎo)入 Lottie 框架。
- 在需要轉(zhuǎn)場(chǎng)的類中,將 Lottie import。
- 因?yàn)?Lottie 實(shí)現(xiàn)的轉(zhuǎn)場(chǎng)實(shí)際上是 Present 的轉(zhuǎn)場(chǎng),所以設(shè)置將要 Present 的控制器的 transitioningDelegate。
- 實(shí)現(xiàn) UIViewControllerTransitioningDelegate 協(xié)議中的幾個(gè)代理方法,返回利用轉(zhuǎn)場(chǎng)動(dòng)畫 json 文件初始化的 LOTAnimationTransitionController 的實(shí)例。
ps:Lottie 轉(zhuǎn)場(chǎng)的 LOTAnimationTransitionController 在 3.0.0 版本后被移除,所以需要使用 Lottie 做轉(zhuǎn)場(chǎng)時(shí),需要在導(dǎo)入時(shí),指定版本號(hào)為更早的版本。我這里使用的是 2.5.3。
實(shí)例
/// 第一個(gè) VC
func presentClick(_ sender: Any) {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "LottieSecondViewController")
vc?.transitioningDelegate = self
self.present(vc!, animated: true) {}
}
/// 實(shí)現(xiàn) UIViewControllerTransitioningDelegate,返回 LOTAnimationTransitionController 的實(shí)例
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
}
}
總結(jié)
上面的所有動(dòng)畫的示例可以在我的Github上找到哦,各位前快去下載把玩吧。
好的轉(zhuǎn)場(chǎng)動(dòng)畫,在用戶交互上會(huì)帶來(lái)更加美妙的體驗(yàn)。讓用戶盡享絲滑哦。
好了,以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。
- iOS實(shí)現(xiàn)抖音點(diǎn)贊動(dòng)畫效果
- iOS實(shí)現(xiàn)點(diǎn)贊動(dòng)畫特效
- iOS仿AirPods彈出動(dòng)畫
- iOS自定義UIButton點(diǎn)擊動(dòng)畫特效
- iOS基于CATransition實(shí)現(xiàn)翻頁(yè)、旋轉(zhuǎn)等動(dòng)畫效果
- iOS實(shí)現(xiàn)轉(zhuǎn)場(chǎng)動(dòng)畫的3種方法示例
- iOS實(shí)現(xiàn)數(shù)字倍數(shù)動(dòng)畫效果
- iOS如何優(yōu)雅地實(shí)現(xiàn)序列動(dòng)畫詳解
- iOS仿抖音視頻加載動(dòng)畫效果的實(shí)現(xiàn)方法
- iOS仿微博導(dǎo)航欄動(dòng)畫(CoreGraphics)的實(shí)現(xiàn)方法
- 詳解 iOS 系統(tǒng)中的視圖動(dòng)畫
相關(guān)文章
iOS中管理剪切板的UIPasteboard粘貼板類用法詳解
在iOS中,通過(guò)UITextField、UITextView和UIWebView剪切或復(fù)制的內(nèi)容都可以通過(guò)UIPasteboard類來(lái)管理粘貼操作,下面就為大家?guī)?lái)iOS中管理剪切板的UIPasteboard粘貼板類用法詳解:2016-06-06
iOS自動(dòng)進(jìn)行View標(biāo)記的方法詳解
這篇文章主要給大家介紹了關(guān)于iOS自動(dòng)進(jìn)行View標(biāo)記的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)各位iOS開(kāi)發(fā)者們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04
分享一個(gè)iOS下實(shí)現(xiàn)基本繪畫板功能的簡(jiǎn)單方法
這篇文章主要介紹了iOS下實(shí)現(xiàn)基本繪畫板功能的簡(jiǎn)單方法,代碼基于傳統(tǒng)的Objective-C,需要的朋友可以參考下2015-10-10
IOS Ble藍(lán)牙開(kāi)發(fā)實(shí)現(xiàn)方法
這篇文章主要為大家詳細(xì)介紹了IOS Ble藍(lán)牙開(kāi)發(fā)的實(shí)現(xiàn)方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-12-12
詳細(xì)整理iOS中UITableView的性能優(yōu)化
最近在微博上看到一個(gè)很好的開(kāi)源項(xiàng)目,是關(guān)于如何優(yōu)化UITableView的,加上正好最近也在優(yōu)化項(xiàng)目中的類似朋友圈功能這塊,思考了很多關(guān)于UITableView的優(yōu)化技巧,所以決定詳細(xì)的整理下對(duì)優(yōu)化UITableView的理解,需要的朋友們可以參考借鑒。2017-03-03
iOS開(kāi)發(fā)之(APNS)遠(yuǎn)程推送實(shí)現(xiàn)代碼 附證書與真機(jī)調(diào)試
這篇文章主要為大家詳細(xì)介紹了iOS開(kāi)發(fā)之(APNS)遠(yuǎn)程推送實(shí)現(xiàn)代碼,附證書與真機(jī)調(diào)試,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09

