onMove bug

I'm not sure where to report this, so here it is.

If you have a list of items and you make them clickable and movable, moving one or more items in the list and then clicking will cause them to move. This is yet another reason that SwiftData needs to track onMove.

Minimal reproducible code:

//
//  ContentView.swift
//  exampleBug
//
//  Create a new project.
//  Replace the default Item class with the one below, and replace ContentView with its class below
// 	Run the app and add a few items a few seconds apart so you can tell them apart.
//  Drag an item to a new position in the list.
//  Click one of the checkboxes and watch the list positions change for no reason!
//

import SwiftUI
import SwiftData

@Model
final class Item {
		var timestamp: Date

		var checkbox: Bool = false

		init(timestamp: Date) {
				self.timestamp = timestamp
		}
}

struct ContentView: View {
	@Environment(\.modelContext) private var modelContext
	@State private var editMode = EditMode.inactive
	@Query private var items: [Item]

	var body: some View {
		NavigationStack {
			List {
				ForEach(items) { item in
					HStack {
						Text(item.timestamp, format: Date.FormatStyle(date: .numeric, time: .standard))
						Button("", systemImage: item.checkbox ? "checkmark.circle.fill" : "circle") {
							item.checkbox.toggle()
							try? modelContext.save()
						}
					}
				}
				.onMove(perform: { indices, newOffset in
					var theItems = items
					theItems.move(fromOffsets: indices, toOffset: newOffset)

				})

			}
			.environment(\.editMode, $editMode)
			.moveDisabled(false)
			.toolbar {
				ToolbarItem(placement: .navigationBarTrailing) {
					EditButton()
				}
				ToolbarItem {
					Button(action: addItem) {
						Label("Add Item", systemImage: "plus")
					}
				}
			}
		}
	}
	func addItem() {
		withAnimation {
			let newItem = Item(timestamp: Date())
			modelContext.insert(newItem)
		}
	}

	func deleteItems(offsets: IndexSet) {
		withAnimation {
			for index in offsets {
				modelContext.delete(items[index])
			}
		}
	}
}

#Preview {
	ContentView()
		.modelContainer(for: Item.self, inMemory: true)
}
code-block

My workaround:

//
//  ContentView.swift
//  exampleBug work around
//
//  This works by using an order attribute in the Item class and a nextOrder state variable
// 	The nextOrder always starts out as 0, which causes the view to call itself sending the count + 1 of the AllItems array from the query.
//  If anyone can find a way to use the results of the query without needing to call the view a second time, that would be great.
//

import SwiftUI
import SwiftData

@Model
final class Item {
	var timestamp: Date
	var order: Int
	var checkbox: Bool = false

	init(timestamp: Date, order: Int) {
		self.timestamp = timestamp
		self.order = order
	}
}

struct ContentView: View {
	@Environment(\.modelContext) private var modelContext
	@State private var editMode = EditMode.inactive
  @State var nextOrder = 0

	@Query(sort: [
		SortDescriptor(\Item.order),
	]
	) public var AllItems: [Item]

	var body: some View {
		if(nextOrder == 0) {
			ContentView.init(nextOrder: AllItems.count + 1)
		} else {
			NavigationStack {
				List {
					ForEach(AllItems) { item in
						HStack {
							Text(item.timestamp, format: Date.FormatStyle(date: .numeric, time: .standard))
							Text(item.order, format: .number)
							Button("", systemImage: item.checkbox ? "checkmark.circle.fill" : "circle") {
								item.checkbox.toggle()
								try? modelContext.save()
							}
						}
					}
					.onMove(perform: { indices, newOffset in
						var theItems = AllItems
						theItems.move(fromOffsets: indices, toOffset: newOffset)
						var order: Int = 1
						theItems.forEach
						{ list in
							list.order = order
							order += 1
						}
					})

				}
				.environment(\.editMode, $editMode)
				.moveDisabled(false)
				.toolbar {
					ToolbarItem(placement: .navigationBarTrailing) {
						EditButton()
					}
					ToolbarItem {
						Button(action: addItem) {
							Label("Add Item", systemImage: "plus")
						}
					}
				}
			}
		}
	}
	func addItem() {
		withAnimation {
			let newItem = Item(timestamp: Date(), order: nextOrder)
			self.nextOrder += 1
			modelContext.insert(newItem)
		}
	}

	func deleteItems(offsets: IndexSet) {
		withAnimation {
			for index in offsets {
				modelContext.delete(AllItems[index])
			}
		}
	}
}

#Preview {
	ContentView()
		.modelContainer(for: Item.self, inMemory: true)
}```

I'm not sure where to report this, so here it is.

The usual place: https://www.apple.com/feedback/

onMove bug
 
 
Q