I ran into this with a more complex project, but was able to recreate with a very simple example below. I have a List with five items in it. I use a ForEach on the items with .onMove. The onMove function has a destination value.
If my list is: A, B, C, D, E, and I drag B so it is below C, I would expect to get A, C, B, D, E. Further, I would expect that destination would be 2, since I am moving B to the 3rd index, assuming that A is at index 0.
Weirdly, destination is always 3.
Conversely, if I do the opposite, and drag C so it is above B, and I get A, C, B, D, E, destination is now 1! This makes sense, since it's the second position.
So why is it that moving down the list results in what appears to be 1-based indexing, but moving it up the list seems to be 0-based indexing? How am I supposed to reliably get the correct destination value?
@State var items = ["A", "B", "C", "D", "E"]
var body: some View {
NavigationStack {
List {
ForEach(items, id: \.self) { item in
Text(item)
}
.onMove(perform: moveItem)
}
.toolbar {
ToolbarItem {
EditButton()
}
}
}
}
private func moveItem(from source: IndexSet, to destination: Int) {
print("destination is \(destination)")
}
}
Output from above. If I drag B below C:
destination is 3
If I drag C above B:
destination is 1