问题
Goal
Update data in a List
on tap
Problem
When .listRowInsets
are applied to the list rows, the list stops getting updates when the state changes.
Code
struct ContentView: View {
private var array = ["a", "b", "c"]
@State private var selectedIndex = 0
var body: some View {
makeBody()
}
private func makeRow(_ t: String, index: Int) -> some View {
return HStack {
Text(t)
Spacer()
if selectedIndex == index {
Image(systemName: "checkmark.circle")
}
}
.contentShape(Rectangle())
.onTapGesture {
print("selected \(index)")
self.selectedIndex = index
}
}
private func makeBody() -> some View {
return List {
ForEach(0..<array.count) { i in
self.makeRow(self.array[i], index: i)
// comment and uncomment this line
// .listRowInsets(EdgeInsets(top: 16, leading: 20, bottom: 16, trailing: 20))
}
}
}
}
Question
Is this a bug? Or am I missing something?
回答1:
If your data can be changed, you need a dynamic ForEach
loop (with an explicit id
parameter):
ForEach(0..<array.count, id:\.self) { i in // <- add `id:\.self`
self.makeRow(self.array[i], index: i)
.listRowInsets(EdgeInsets(top: 16, leading: 20, bottom: 16, trailing: 20))
}
It's not well documented though. In some cases Xcode warns you when you try to modify your array used in a ForEach loop:
ForEach(_:content:)
should only be used for constant data. Instead conform data toIdentifiable
or useForEach(_:id:content:)
and provide an explicitid
!
来源:https://stackoverflow.com/questions/62666863/swiftui-list-not-getting-updated-when-listrowinsets-are-applied