如何在 Objective-C 中播放 Lottie 动画

Posted

技术标签:

【中文标题】如何在 Objective-C 中播放 Lottie 动画【英文标题】:How to play Lottie animations in Objective-C 【发布时间】:2018-06-30 07:14:21 【问题描述】:

我已经为 Lottie 安装了 pod 文件并从 lottiefiles.com 下载了 hello.json 文件

 LOTAnimationView *Hello_loader;
 Hello_loader = [LOTAnimationView animationNamed:@"hello"];
 [self.view addSubview:Hello_loader];

我在viewDidLoad()viewDidAppear() 都试过了,但还是没有出现

我是这个 ios 编程的新手,谁能帮我解决这个问题?提前谢谢...

【问题讨论】:

【参考方案1】:

在 Lottie 3 中,Animation 类是可编码的,不能直接在 Objective-C 中使用。所以我创建了一个包装器,它允许在 Objevtice-C 中使用类似的 api(受 this 启发):

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()
    

    // MARK: - Public Functions

    @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")
            
        
    

    /**
     Plays the animation from its current state to the end.

     - Parameter completion: An optional completion closure to be called when the animation completes playing.
     */
    @objc func play(completion: LottieCompletionBlock? = nil) 
        animationView.play(completion: completion)
    

    /**
     Pauses the animation in its current state.

     The completion closure will be called with `false`
     */
    public func pause() 
        animationView.pause()
    

    /**
     Stops the animation and resets the view to its start frame.

     The completion closure will be called with `false`
     */
    @objc func stop() 
        animationView.stop()
    

    // MARK: Play with progress

    /**
     Plays the animation from a progress (0-1) to a progress (0-1).

     - Parameter fromProgress: The start progress of the animation.
     - Parameter toProgress: The end progress of the animation.
     - Parameter loopMode: The loop behavior of the animation.
     - Parameter completion: An optional completion closure to be called when the animation stops.
     */
    @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)
    

    /**
     Plays the animation from a progress (0-1) to a progress (0-1). The view's `loopMode` property will be used.

     - Parameter fromProgress: The start progress of the animation.
     - Parameter toProgress: The end progress of the animation.
     - Parameter completion: An optional completion closure to be called when the animation stops.
     */
    @objc func play(fromProgress from: AnimationProgressTime,
                    toProgress to: AnimationProgressTime,
                    completion: LottieCompletionBlock? = nil) 
        animationView.play(fromProgress: from, toProgress: to, loopMode: nil, completion: completion)
    

    /**
     Plays the animation from the current progress to a progress (0-1).

     - Parameter toProgress: The end progress of the animation.
     - Parameter loopMode: The loop behavior of the animation.
     - Parameter completion: An optional completion closure to be called when the animation stops.
     */
    @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)
    

    /**
     Plays the animation from the current progress to a progress (0-1). The view's `loopMode` property will be used

     - Parameter toProgress: The end progress of the animation.
     - Parameter completion: An optional completion closure to be called when the animation stops.
     */
    @objc func play(toProgress to: AnimationProgressTime,
                    completion: LottieCompletionBlock? = nil) 
        animationView.play(fromProgress: nil, toProgress: to, loopMode: nil, completion: completion)
    

    // MARK: Play with frame

    /**
     Plays the animation from a start frame to an end frame in the animation's framerate.

     - Parameter fromFrame: The start frame of the animation.
     - Parameter toFrame: The end frame of the animation.
     - Parameter loopMode: The loop behavior of the animation.
     - Parameter completion: An optional completion closure to be called when the animation stops.
     */
    @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)
    

    /**
     Plays the animation from a start frame to an end frame in the animation's framerate. The view's `loopMode` property will be used.

     - Parameter fromFrame: The start frame of the animation.
     - Parameter toFrame: The end frame of the animation.
     - Parameter completion: An optional completion closure to be called when the animation stops.
     */
    @objc func play(fromFrame from: AnimationFrameTime,
                    toFrame to: AnimationFrameTime,
                    completion: LottieCompletionBlock? = nil) 
        animationView.play(fromFrame: from, toFrame: to, loopMode: nil, completion: completion)

    

    /**
     Plays the animation from the current frame to an end frame in the animation's framerate.

     - Parameter toFrame: The end frame of the animation.
     - Parameter loopMode: The loop behavior of the animation.
     - Parameter completion: An optional completion closure to be called when the animation stops.
     */
    @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)

    

    /**
     Plays the animation from the current frame to an end frame in the animation's framerate. The view's `loopMode` property will be used.

     - Parameter toFrame: The end frame of the animation.
     - Parameter completion: An optional completion closure to be called when the animation stops.
     */
    @objc func play(toFrame to: AnimationFrameTime,
                    completion: LottieCompletionBlock? = nil) 
        animationView.play(fromFrame: nil, toFrame: to, loopMode: nil, completion: completion)
    

    // MARK: Play with marker

    /**
     Plays the animation from a named marker to another marker.

     Markers are point in time that are encoded into the Animation data and assigned
     a name.

     NOTE: If markers are not found the play command will exit.

     - Parameter fromMarker: The start marker for the animation playback.
     - Parameter toMarker: The end marker for the animation playback.
     - Parameter loopMode: The loop behavior of the animation.
     - Parameter completion: An optional completion closure to be called when the animation stops.
     */
    @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)
    

    /**
     Plays the animation from a named marker to another marker. The view's `loopMode` property will be used.

     Markers are point in time that are encoded into the Animation data and assigned
     a name.

     NOTE: If markers are not found the play command will exit.

     - Parameter fromMarker: The start marker for the animation playback.
     - Parameter toMarker: The end marker for the animation playback.
     - Parameter completion: An optional completion closure to be called when the animation stops.
     */
    @objc func play(fromMarker from: String,
                    toMarker to: String,
                    completion: LottieCompletionBlock? = nil) 
        animationView.play(fromMarker: from, toMarker: to, loopMode: nil, completion: completion)
    

    /**
     Plays the animation the current progress to a named marker.

     Markers are point in time that are encoded into the Animation data and assigned
     a name.

     NOTE: If markers are not found the play command will exit.

     - Parameter toMarker: The end marker for the animation playback.
     - Parameter loopMode: The loop behavior of the animation.
     - Parameter completion: An optional completion closure to be called when the animation stops.
     */
    @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)
    

    /**
     Plays the animation from the current progress to named marker. The view's `loopMode` property will be used.

     Markers are point in time that are encoded into the Animation data and assigned
     a name.

     NOTE: If markers are not found the play command will exit.

     - Parameter toMarker: The end marker for the animation playback.
     - Parameter completion: An optional completion closure to be called when the animation stops.
     */
    @objc func play(toMarker to: String,
                    completion: LottieCompletionBlock? = nil) 
        animationView.play(fromMarker: nil, toMarker: to, loopMode: nil, completion: completion)
    

    // MARK: - Private

    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];

【讨论】:

加载器添加后为什么要添加为子视图?这对我来说似乎有点奇怪。【参考方案2】:

Swift 5(带有最新版本的lottie)

    let animationView = AnimationView(name: "Bubbles") //Replace "Bubbles" with your animation file name.
    animationView.frame = CGRect(x: 0, y: 0, width: 150, height: 150)
    animationView.center = self.view.center
    animationView.loopMode = .loop
    animationView.backgroundBehavior = .pauseAndRestore //to pause in background and restart when it reach foreground
    self.view.addSubview(animationView)
    animationView.play()

Check output on this link

【讨论】:

【参考方案3】:

试试这个

 LOTAnimationView *hello_loader = [LOTAnimationView animationNamed:@"hello"];
 [self.view addSubview:hello_loader];
 [hello_loader play];

【讨论】:

仍然无法正常工作...它正在查看@IOS 的空白页面 试试这个 [self. Hello_loader 播放]; 上面的代码抛出错误[Property 'hello_loader' not found on object of type 'ViewController *'] 检查已编辑的答案,因为您已经声明了 Hello_loader 对象 它正在工作...但不是我希望它只是显示线条但我想显示的链接在上面你能帮我吗

以上是关于如何在 Objective-C 中播放 Lottie 动画的主要内容,如果未能解决你的问题,请参考以下文章

Objective-C 播放声音

Objective-C 如何立即在 MPMoviePlayerController 或 AVPlayer 上播放视频,没有延迟?

iOS(Objective-C)在AudioQueue中播放AAC文件的问题

在 Objective-C 中无延迟播放音效

Objective-C:在 App 上播放 Youtube 视频

从 sqlite 数据库 Objective-C 播放音频文件