As I know View in SwiftUI will get updated only if @Binding or @State values haven been modified. However in below example, each time clicking the button (modify one element of the list), all three sub view will be updated (text background color change).
What I want to achieve is make it only update the corresponding view while modifying item in the list.
What's more, instead of @Binding, if change to @State for ItemView's variable value (which is "content"), once click the button, all three text background will change, but the text stay same. I understand the reason of no text change, but why all background changed?
Thanks!
============
View
struct ContentView: View {
@ObservedObject var vm: VM = VM()
var body: some View {
ForEach($vm.valList, id: \.id) { $item in
ItemView(content: $item)
.background(.random)
}
Button("Increment", action: {
vm.increment()
})
}
}
struct ItemView: View {
@Binding var content: Model
var body: some View {
print("\(content.testVal) updated")
return Text(String(content.testVal))
}
}
extension ShapeStyle where Self == Color {
static var random: Color {
Color(
red: .random(in: 0...1),
green: .random(in: 0...1),
blue: .random(in: 0...1)
)
}
}
VM
class VM: ObservableObject {
@Published var valList: [Model] = []
init(){
let m0 = Model(testVal: 0)
let m1 = Model(testVal: 1)
let m2 = Model(testVal: 2)
valList = [m0, m1, m2]
}
func increment() {
valList[0].testVal += 1
print("Increment: \(valList[0].testVal)")
}
}
Model
struct Model {
var id: UUID = UUID()
var testVal: Int
}