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
相关产品推荐
相关产品推荐

