In my recent project, a @State variable was not set after set.
self.project?.currentTransUnit?.isVerified = true
self.project?.update() // debug point.
// po "self.project?.currentTransUnit?.isVerified" prints false.
So I created another project to narrow the issue.
//
// Model_SampleApp.swift
// Model Sample
//
// Created by zhaoxin on 2022/8/28.
//
import SwiftUI
@main
struct Model_SampleApp: App {
@State private var foo:Foo? = Foo(bar: Bar(item: Item(name: "Johnny")))
var body: some Scene {
WindowGroup {
ContentView(foo: $foo)
}
}
}
//
// ContentView.swift
// Model Sample
//
// Created by zhaoxin on 2022/8/28.
//
import SwiftUI
struct ContentView: View {
@Binding var foo:Foo?
var body: some View {
VStack {
Text(foo?.bar.item.name ?? "nil")
HStack {
TextField("name", text: Binding(get: {
foo?.bar.item.name ?? "nil"
}, set: { newValue in
foo?.bar.item.name = newValue
}))
}
}
.padding()
.onChange(of: foo) { newValue in
print(newValue)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(foo: .constant(nil))
}
}
//
// Model.swift
// Model Sample
//
// Created by zhaoxin on 2022/8/28.
//
import Foundation
struct Foo:Equatable {
var bar:Bar
}
struct Bar:Equatable {
var item:Item
}
struct Item:Equatable {
var name:String
let id = UUID()
}
All things went fine. I noticed that onChange
required Equatable
. So I did a test.
func onChange<V>(of value: V, perform action: @escaping (V) -> Void) -> some View where V : Equatable
struct Item:Equatable {
var name:String
let id = UUID()
static func == (lhs: Item, rhs: Item) -> Bool {
return lhs.id == rhs.id
}
}
Now the issue happened again. So I guess for optimize performance. When set to a @State variable, SwiftUI compared the previous and current value by Equatable. If they were the same, SwiftUI thought they were identical and didn't replace that current with the previous value. So if we implemented the Equatable's method with part implementation on purpose, the issue appeared on the values which were not mentioned in Equatable's method.