thecanteen
thecanteen

Reputation: 784

TextField in List - onMove leads to "ID occurs multiple times" warning

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)
    }
    
}

Upvotes: 3

Views: 810

Answers (1)

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.

Upvotes: 2

Related Questions