You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI中如何判断Rive动画是否播放完毕?

监听Rive启动动画完成并切换主内容

对于无状态机的简单Rive动画,你可以通过监听动画的停止事件来判断播放完成,进而切换到应用主内容。以下是两种实用的实现方式:

方式一:使用闭包回调

直接通过RiveViewModel的onStop闭包监听动画结束,更新状态变量切换视图:

struct MainView: View {
    @State private var animationFinished = false
    private let openingAnimation: RiveViewModel
    
    init() {
        let viewModel = RiveViewModel(fileName: "opening_animation")
        // 配置动画为单次播放(避免循环)
        viewModel.setLoop(.oneShot)
        // 监听动画停止事件
        viewModel.onStop = { _ in
            // 确保在主线程更新UI状态
            DispatchQueue.main.async {
                animationFinished = true
            }
        }
        self.openingAnimation = viewModel
    }
    
    var body: some View {
        Group {
            if animationFinished {
                // 替换为你的应用主内容
                Text("应用主内容")
                    .font(.largeTitle)
                    .frame(maxWidth: .infinity, maxHeight: .infinity)
            } else {
                openingAnimation.view()
                    .onAppear {
                        // 手动触发动画播放(若动画未自动启动)
                        openingAnimation.play()
                    }
            }
        }
    }
}

方式二:使用Delegate协议

通过实现RiveViewModelDelegate协议来监听动画状态变化:

struct MainView: View {
    @State private var animationFinished = false
    private let openingAnimation: RiveViewModel
    
    init() {
        let viewModel = RiveViewModel(fileName: "opening_animation")
        viewModel.delegate = self
        viewModel.setLoop(.oneShot)
        self.openingAnimation = viewModel
    }
    
    var body: some View {
        Group {
            if animationFinished {
                Text("应用主内容")
                    .font(.largeTitle)
                    .frame(maxWidth: .infinity, maxHeight: .infinity)
            } else {
                openingAnimation.view()
                    .onAppear {
                        openingAnimation.play()
                    }
            }
        }
    }
}

// 实现RiveViewModelDelegate协议
extension MainView: RiveViewModelDelegate {
    func riveViewModel(_ viewModel: RiveViewModel, didStopAnimation name: String) {
        animationFinished = true
    }
}

关键注意点

  • 必须设置loop为.oneShot:确保动画只播放一次,播放结束后会触发停止事件
  • 手动触发播放:部分Rive动画不会自动启动,需要在onAppear中调用play()
  • 主线程更新UI:动画回调可能在后台线程执行,切换状态时要确保在主线程操作(闭包方式中已做处理,Delegate方式默认在主线程,但建议保持习惯)

内容的提问来源于stack exchange,提问作者thecanteen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 01:46:19