swiftswiftuirive

rive computed var not accepting input


I'm having an issue updating the input of a rive animation in swiftui.

I'm trying to set the filename using a computed property, so it will update from a viewmodel's name property.

It works, and loads the right file, but while using the computed property, the inputs no longer work.

// Viewmodel which stores the name 
@ObservedObject var vm: ContentViewModel

// Property that is updated, have tried var, private var, and @State vars
@State private var timerPercentage: Double = 100.0

    // Computer property, taking filename from ViewModel above
    var animation: RiveViewModel {
        // Initialise the animation, using name
        RiveViewModel(fileName: "(vm.name)")
    }

    var body: some View {
        VStack(alignment: .center) {

        // Rive animation
        animation
               .view()
               .frame(height: UIScreen.main.bounds.width * 0.75)
        }
    }

    // Function to update the property - this works when not using computed porperty
    func changeValue() {
        animation.setInput("height", value: Double(timerPercentage))
    }

Any tips of how I can get this working?


Solution

  • I got this working by creating a reference to the RiveViewModel as a let, rather than a var, inside the body of my View. Then, rather than having changevalue() be a func, I brought it into the onChange modifier of the view.

    In case anyone else needs to do this in the future.

    struct ContentView: View {
    
        // Viewmodel which stores the name 
        @ObservedObject var vm: ContentViewModel
    
        // Property that is updated, have tried var, private var, and @State vars
        @State private var timerPercentage: Double = 100.0
    
        var body: some View {
             let animation = RiveViewModel(fileName: "(vm.name)")
             VStack(alignment: .center) {
    
             // Rive animation
             animation
                   .view()
                   .frame(height: UIScreen.main.bounds.width * 0.75)
             }.onChange(of: timerPercentage) { newValue in
                    animation.setInput("height", value: Double(timerPercentage))
                }
         }