I am testing out Asperi's great answer to reordering cells:
SwiftUI | Using onDrag and onDrop to reorder Items within one single LazyGrid?
The issue I have is the overlay does not reset when I simply enter drag mode and then drop in place, see cell 3:
I am using the exact code as found on the answer. So it seems like this line:
.overlay(dragging?.id == d.id ? Color.white.opacity(0.8) : Color.clear)
is not reacting properly?
Any idea how I can make the overlay to update and go back to clear
?
Actually it is a SwiftUI bug, because in this scenario onDrag
is called, but onDrop
is NOT (that's wrong from D&D flow perspective).
A possible workaround is to introduce additional in-progress state that will indicate that D&D really started. (Actually I would think about some refactoring to simplify delegate's interface, but for demo it is ok).
Tested with Xcode 13.3 / iOS 15.4
Here are changes:
@State private var isUpdating = false // in-progress state
// ...
.overlay(dragging?.id == d.id && isUpdating ? // << additional condition
Color.white.opacity(0.8) : Color.clear)
// ...
.onDrop(of: [UTType.text], delegate: DragRelocateDelegate(item: d, listData: $model.data,
current: $dragging, updating: $isUpdating)) // << transfer into delegate
// ...
func dropEntered(info: DropInfo) {
updating = true // << indicate that D&D begins
// ...
func performDrop(info: DropInfo) -> Bool {
self.updating = false // << D&D finished