I am testing out the solution provided by Asperi
here:
SwiftUI | Using onDrag and onDrop to reorder Items within one single LazyGrid?
so,
what I would like to do is to add a contextMenu
on a cell, and if the user chooses to reorder cells, then would enable the onDrag and onDrop gestures.
I looked into the simultaneousGesture
but, I am not sure how trigger the contextMenu while the view also has onDrag attached to it.
so I tried something like this:
...............
ScrollView(.vertical, showsIndicators: true) {
LazyVGrid(columns: gridItems, spacing: 0) {
ForEach(model.data) { d in
GridItemView(d: d)
.frame(width: side, height: side)
.overlay(dragging?.id == d.id ? Color.white.opacity(0.8) : Color.clear)
.contextMenu {
Button {
editCells.toggle()
} label: {
Label("Edit...", systemImage: "pencil")
}
// other options .....
}
.onDrag {
self.dragging = d
return NSItemProvider(object: String(d.id) as NSString)
}
.disabled(!editCells)
.onDrop(of: [UTType.text], delegate: DragRelocateDelegate(item: d, listData: $model.data, current: $dragging))
.disabled(!editCells)
}
}
.animation(.default, value: model.data)
...............
So, the contextMenu never triggers unless I remove the onDrag and onDrop gestures first.
Is there a way to use the contextMenu to "enter" an edit mode to allow drag and drop? Is there a way to make it work while the onDrag and onDrop gestures are installed on the view?
Asperi is right. For the curious as to how I got around doing this I used this conditional View extension:
extension View {
/// Applies the given transform if the given condition evaluates to `true`.
/// - Parameters:
/// - condition: The condition to evaluate.
/// - transform: The transform to apply to the source `View`.
/// - Returns: Either the original `View` or the modified `View` if the condition is `true`.
@ViewBuilder func `if`<Content: View>(_ condition: Bool, transform: (Self) -> Content) -> some View {
if condition {
transform(self)
} else {
self
}
}
}