I have a swiftUi view depending on a class data. Before displaying the data, I have to compute it in .onAppear method.
I would like to make this heavy computation only when my observed object changes.
The problem is that .onAppear is called every time I open the view, but the object value does not change very often.
Is it possible to conditionally execute the compute function, only when observed data has effectively been modified ?
import SwiftUI
struct test2: View {
@StateObject var person = Person()
@State private var computedValue = 0
var body: some View {
List {
Text("age = \(person.age)")
Text("computedValue = \(computedValue)")
}
.onAppear {
computedValue = compute(person.age) /// Executed much too often :(
}
}
func compute(_ age: Int) -> Int {
return age * 2 /// In real life, heavy computing
}
}
class Person: ObservableObject {
var age: Int = 0
}
Thanks for advice :)
It would probably be a little less code in the view model, but to do all of the calculations in the view, you will need a few changes. First, your
class Personhas no@Publishedvariables, so it will never call for a state change. I have fixed that.Second, now that your state will update, you can add an
.onReceive()to the view to keep track of whenageupdates.Third, and extremely important, to keep from blocking the main thread with the "heavy computing", you should implement Async Await. As a result, even though I sleep the thread for 3 seconds, the UI is still fluid.