一. 問題背景
UI
給了一份地址欄的背景框的lottie
動畫的json
文件,我用版本為3.3.0
的lottie-ios
庫的AnimationView
直接加載略步,出來的lottie
動畫背景框诈悍,有一段邊框會消失型宝。
lazy var firstAnimationView: AnimationView = {
let animation = AnimationView(name: "dest_animation")
animation.loopMode = .loop
animation.backgroundBehavior = .pauseAndRestore
return animation
}()
效果圖:
二. 問題排查
因為統(tǒng)一的lottie
動畫的json
文件在安卓上是顯示正常的外盯,因為lottie
是三方庫惭墓,因此特意去官網(wǎng)和github
查了下虹钮,lottie
對安卓和iOS
支持的差異聋庵,
然后將lottie
動畫的json
一段一段分析調(diào)試也沒找到原因,后來我去github
提了issues
然后作者回復(fù)了下芙粱,說lottie
的3.4.0
以上版本,可以直接采用Core Animation
渲染引擎祭玉,能保證動畫執(zhí)行穩(wěn)定順暢。
我試了下春畔,采用了lottie
的3.5.0
的版本脱货,采用Core Animation
渲染引擎岛都,果然顯示正常:
// MARK: - Lazy
lazy var firstAnimationView: LottieAnimationView = {
let animation = LottieAnimationView(name: "dest_animation")
animation.loopMode = .loop
animation.backgroundBehavior = .pauseAndRestore
return animation
}()
lazy var secondAnimationView: LottieAnimationView = {
let config = LottieConfiguration(renderingEngine: .coreAnimation, decodingStrategy: .codable)
let animation = LottieAnimationView(name: "dest_animation", configuration: config)
animation.loopMode = .loop
animation.backgroundBehavior = .pauseAndRestore
return animation
}()
從效果圖可以看出,第一個lottie
動畫采用主線程的渲染引擎蹭劈,第二個lottie
動畫采用了Core Animation
的渲染引擎疗绣。
去官網(wǎng)查了下資料: https://github.com/airbnb/lottie-ios/discussions/1627
Lottie
[3.4.0](https://github.com/airbnb/lottie-ios/releases/tag/3.4.0)
is now available! This release adds a new rendering engine that uses Core Animation instead of animating on the main thread. This significantly improves animation performance while also eliminating CPU overhead.Lottie’s original rendering engine played its animations on the app’s main thread. Once per frame, Lottie advanced the progress of the animation and re-rendered its content. This meant that:
- Animations would consume 5-20%+ of the CPU while playing, leaving fewer CPU cycles available for the rest of the application.
- Animations would not update when the main thread was busy, which could cause animations to drop frames or freeze entirely.
Lottie
3.4.0
includes a new rendering engine that addresses these issues and significantly improves performance. The new engine leverages Core Animation to render out-of-process with GPU hardware acceleration. Once animations begin playing, they do not consume any of the app’s CPU resources, and are effectively guaranteed to animate smoothly regardless of CPU load:
這里意思就是lottie
動畫采用主線程的渲染引擎,動畫的每一幀是由主線程來更新铺韧,并提交渲染多矮,因此受限于主線程runloop
是否繁忙,也使得CPU
功能繁忙哈打。而lottie
動畫采用Core Animation
的渲染引擎塔逃,則是將動畫渲染提交到Core Animation
去處理,Core Animation
直接調(diào)用Gpu
去渲染料仗,這個過程不受主線程runloop
限制湾盗,也不占用CPU
能保證動畫運行的順暢。
但同時用lottie
的3.5.0
測試立轧,在iOS13
以下的系統(tǒng)格粪,發(fā)現(xiàn)該lottie
動畫竟然不顯示,斷點調(diào)試了下源碼氛改,發(fā)現(xiàn)是CGColor
分類的rgb
顏色方法這里有問題:
return CGColor(
colorSpace: CGColorSpaceCreateDeviceRGB(),
components: [red, green, blue])!.copy()!
這個方法默認返回的顏色的alpha
為0
導(dǎo)致帐萎,動畫不顯示,因此對這里改動了如下:
CGColor(
colorSpace: CGColorSpaceCreateDeviceRGB(),
components: [red, green, blue])!.copy(alpha: 1)!
將顏色值的透明度alpha
默認設(shè)置為1
胜卤。
同時也在github
再次提了issues
[lottie動畫3.5.0版本在iOS13以下系統(tǒng)不顯示]
而作者也給了回復(fù)疆导,說他兩周前也發(fā)現(xiàn)這個問題,提了修復(fù)葛躏,但是還沒發(fā)新版本澈段,修復(fù)提交如下:
因此作者建議我采用最新的master
代碼。
三. 解決方案
最終我采用lottie
的3.5.0
版本再加上對iOS13
以下系統(tǒng)顏色修復(fù)的提交舰攒,并將lottie
動畫制作為二方庫败富,而對于具體代碼修改:可以在每個動畫指定渲染引擎:
- 單個
lottie
動畫指定渲染引擎
lazy var secondAnimationView: LottieAnimationView = {
let config = LottieConfiguration(renderingEngine: .coreAnimation, decodingStrategy: .codable)
let animation = LottieAnimationView(name: "dest_animation", configuration: config)
animation.loopMode = .loop
animation.backgroundBehavior = .pauseAndRestore
return animation
}()
- 也可以指定全局范圍的自動選擇渲染引擎,默認優(yōu)先選擇
Core Animation
渲染引擎摩窃,如果Core Animation
解析渲染失敗兽叮,則會調(diào)用主線程渲染引擎進行渲染
LottieConfiguration.shared.renderingEngine = .automatic