I have a simple list that contains a textfield for each word object (just a string with an ID)
When I try to move rows in my app, XCode prints this warning in the console:
"ForEach<Binding<Array>, UUID, TextField>: the ID D5F23F6F-82BB-43AD-9ECF-DEA1B56AB345 occurs multiple times within the collection, this will give undefined results!"
Why is this so?
No warning occurs if I use Text instead of TextField.
This is my word struct:
struct Word: Identifiable, Hashable {
let id: UUID = UUID()
var str: String
init(_ str: String) {
self.str = str
}
}
And my list looks like this:
struct ReorderTest: View {
@State private var items = [Word("Chicken"), Word("Pork"), Word("Beef")]
var body: some View {
NavigationView {
List {
// USING TEXTFIELD LEADS TO WARNINGS
ForEach($items, id: \.self.id) { $item in
TextField("item", text: $item.str)
}
// USING TEXT DOES NOT LEAD TO WARNINGS
// ForEach(items, id: \.self.id) { item in
// Text(item.str)
// }
.onMove(perform: move)
.onDelete(perform: delete)
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
EditButton()
}
}
}
}
func delete(at offsets: IndexSet) {
self.items.remove(atOffsets: offsets)
}
func move(from source: IndexSet, to destination: Int) {
self.items.move(fromOffsets: source, toOffset: destination)
}
}
CodePudding user response:
try this, works for me:
func move(from source: IndexSet, to destination: Int) {
DispatchQueue.main.async {
self.items.move(fromOffsets: source, toOffset: destination)
}
}
Note, you could simply use ForEach($items)
, since Word
is Identifiable
. Why does this happens, I have no idea, we do not have access to the code for the move
.