在 Lottie 3 中,
Animation
类是Codable类型,并且在Objective-C中不能直接使用。因此,我创建了一个包装器,允许在Objective-C中使用类似的api(灵感来自于
这里):
import Foundation
import UIKit
import Lottie
@objc(AnimationView) class Z_OBJC_Wrapper_AnimationView: UIView {
@objc var loop:Bool {
get {
return animationView.loopMode == .loop
}
set {
animationView.loopMode = newValue ? .loop : .playOnce
}
}
@objc var speed:CGFloat {
get {
return animationView.animationSpeed
}
set {
animationView.animationSpeed = newValue
}
}
@objc var progress:AnimationProgressTime {
get {
return animationView.currentProgress
}
set {
animationView.currentProgress = newValue
}
}
private let animationView: AnimationView
@objc override init(frame: CGRect) {
animationView = AnimationView()
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
animationView = AnimationView()
super.init(coder: aDecoder)
commonInit()
}
@objc func loadAnimation(name animationName:String) {
if let path = Bundle.main.path(forResource: animationName, ofType: "json") {
do {
let data = try Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe)
let animation:Animation = try JSONDecoder().decode(Animation.self, from: data)
animationView.animation = animation
} catch {
assertionFailure("Could not read Lottie json file")
}
}
}
@objc func play(completion: LottieCompletionBlock? = nil) {
animationView.play(completion: completion)
}
public func pause() {
animationView.pause()
}
@objc func stop() {
animationView.stop()
}
@objc func play(fromProgress from: AnimationProgressTime,
toProgress to: AnimationProgressTime,
loop loopBool: Bool,
completion: LottieCompletionBlock? = nil) {
let loopMode:LottieLoopMode = loopBool ? .loop : .playOnce
animationView.play(fromProgress: from, toProgress: to, loopMode: loopMode, completion: completion)
}
@objc func play(fromProgress from: AnimationProgressTime,
toProgress to: AnimationProgressTime,
completion: LottieCompletionBlock? = nil) {
animationView.play(fromProgress: from, toProgress: to, loopMode: nil, completion: completion)
}
@objc func play(toProgress to: AnimationProgressTime,
loop loopBool: Bool,
completion: LottieCompletionBlock? = nil) {
let loopMode:LottieLoopMode = loopBool ? .loop : .playOnce
animationView.play(fromProgress: nil, toProgress: to, loopMode: loopMode, completion: completion)
}
@objc func play(toProgress to: AnimationProgressTime,
completion: LottieCompletionBlock? = nil) {
animationView.play(fromProgress: nil, toProgress: to, loopMode: nil, completion: completion)
}
@objc func play(fromFrame from: AnimationFrameTime,
toFrame to: AnimationFrameTime,
loop loopBool: Bool,
completion: LottieCompletionBlock? = nil) {
let loopMode:LottieLoopMode = loopBool ? .loop : .playOnce
animationView.play(fromFrame: from, toFrame: to, loopMode: loopMode, completion: completion)
}
@objc func play(fromFrame from: AnimationFrameTime,
toFrame to: AnimationFrameTime,
completion: LottieCompletionBlock? = nil) {
animationView.play(fromFrame: from, toFrame: to, loopMode: nil, completion: completion)
}
@objc func play(toFrame to: AnimationFrameTime,
loop loopBool: Bool,
completion: LottieCompletionBlock? = nil) {
let loopMode:LottieLoopMode = loopBool ? .loop : .playOnce
animationView.play(fromFrame: nil, toFrame: to, loopMode: loopMode, completion: completion)
}
@objc func play(toFrame to: AnimationFrameTime,
completion: LottieCompletionBlock? = nil) {
animationView.play(fromFrame: nil, toFrame: to, loopMode: nil, completion: completion)
}
@objc func play(fromMarker from: String,
toMarker to: String,
loop loopBool: Bool,
completion: LottieCompletionBlock? = nil) {
let loopMode:LottieLoopMode = loopBool ? .loop : .playOnce
animationView.play(fromMarker: from, toMarker: to, loopMode: loopMode, completion: completion)
}
@objc func play(fromMarker from: String,
toMarker to: String,
completion: LottieCompletionBlock? = nil) {
animationView.play(fromMarker: from, toMarker: to, loopMode: nil, completion: completion)
}
@objc func play(toMarker to: String,
loop loopBool: Bool,
completion: LottieCompletionBlock? = nil) {
let loopMode:LottieLoopMode = loopBool ? .loop : .playOnce
animationView.play(fromMarker: nil, toMarker: to, loopMode: loopMode, completion: completion)
}
@objc func play(toMarker to: String,
completion: LottieCompletionBlock? = nil) {
animationView.play(fromMarker: nil, toMarker: to, loopMode: nil, completion: completion)
}
private func commonInit() {
translatesAutoresizingMaskIntoConstraints = false
setUpViews()
}
private func setUpViews() {
animationView.translatesAutoresizingMaskIntoConstraints = false
addSubview(animationView)
animationView.topAnchor.constraint(equalTo: topAnchor).isActive = true
animationView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
animationView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
animationView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
}
}
在Objective-C中的使用:
AnimationView *loader = [[AnimationView alloc] initWithFrame:CGRectMake(0, 0, 32, 32)];
[loader loadAnimationWithName:@"loader"];
[loader playWithCompletion:nil];
[self addSubview:loader];