SwiftUI中使用计算属性加载Rive动画后无法更新输入的问题
SwiftUI中Rive动画setInput失效的解决方法
问题根源
你用计算属性返回RiveViewModel的写法,会导致每次访问该属性时都创建一个全新的实例:
- 界面渲染调用
animation.view()时,生成的是实例A - 执行
changeValue()调用animation.setInput(...)时,操作的是实例B
两个实例完全独立,所以修改实例B的输入不会影响界面上的实例A,自然看不到动画变化。
解决方案
把计算属性改成状态变量存储RiveViewModel实例,同时监听vm.name的变化来更新实例,确保界面和代码操作的是同一个对象:
修改后的代码示例:
@ObservedObject var vm: ContentViewModel @State private var timerPercentage: Double = 100.0 // 用@State存储RiveViewModel实例,保证全局唯一 @State private var animation: RiveViewModel? var body: some View { VStack(alignment: .center) { if let animation = animation { animation .view() .frame(height: UIScreen.main.bounds.width * 0.75) } } // 监听文件名变化,及时更新RiveViewModel .onChange(of: vm.name) { newName in animation = RiveViewModel(fileName: newName) } // 视图加载时初始化第一个实例 .onAppear { animation = RiveViewModel(fileName: vm.name) } } func changeValue() { animation?.setInput("height", value: timerPercentage) }
额外说明
- 使用
@State存储实例,能确保在视图整个生命周期内,界面显示和代码操作的是同一个RiveViewModel对象 - 通过
onChange(of: vm.name)监听文件名变更,保证切换动画文件时能同步更新实例,同时保留输入控制能力 - 增加
onAppear初始化逻辑,避免视图刚加载时出现动画空白
内容的提问来源于stack exchange,提问作者byrnec25
相关产品推荐
相关产品推荐

