1

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:

enter image description here

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?

zumzum
  • 17,984
  • 26
  • 111
  • 172

1 Answers1

2

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

Asperi
  • 228,894
  • 20
  • 464
  • 690