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

Time:06-11

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.

  • Related