Here is my code (Running on macOS 11.7.2,so it needs old version macOS compatibility >= 11.0):
struct ContentView: View {
@State private var users = ["Paul", "Taylor", "Adele"]
var body: some View {
List {
ForEach(users, id: \.self) { user in
Text(user)
.onTapGesture(count: 2) {
}
}
.onMove { source, destination in
users.move(fromOffsets: source, toOffset: destination)
}
}
.frame(width: 200,height: 200)
.background(Color.white)
.cornerRadius(10)
.position(x: 500, y:300)
}
}
if I comment out the .onTapGesture
modifier,I can drag on any area of the view to reorder the list, but if I enable the .onTapGesture
modifier, I can't do that anymore unless I drag outside the area of Text()
(while still inside the row view of course).
Can I keep the .onTapGesture
modifier while keeping it draggable to reorder the List?
I think I just found a perfect solution, which comes from this so
Here is my code:
class TapHandlerView: NSView {
var doubleClickAction: () -> Void
init(_ block: @escaping () -> Void) {
self.doubleClickAction = block
super.init(frame: .zero)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func mouseDown(with event: NSEvent) {
if event.clickCount == 2 {
doubleClickAction()
}
super.mouseDown(with: event) // keep this to allow drag !!
}
}
struct TapHandler: NSViewRepresentable {
let doubleClickAction: () -> Void
func makeNSView(context: Context) -> TapHandlerView {
TapHandlerView(doubleClickAction)
}
func updateNSView(_ nsView: TapHandlerView, context: Context) {
nsView.doubleClickAction = doubleClickAction
}
}
And I use it like this:
ForEach(users, id: \.self) { user in
Text(user)
.overlay(
TapHandler(doubleClickAction: {
//Put your code here.
})
}
Now, my list supports double click and drag reordering, at the same time!