0

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?

byrnec25
  • 29
  • 5
  • Are you expecting the view to update when you call changeValue?? Did you mean to use a state var? – matt Jul 28 '23 at 21:15
  • Yes the var is updated every second based on a timer. I’ve left out some code as this view is quite large. – byrnec25 Jul 28 '23 at 21:21

1 Answers1

1

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))
            }
     }
byrnec25
  • 29
  • 5