Wie kann ich einen Rechtsklick in SwiftUI erkennen?


10

Ich schreibe eine einfache Mines-App , um SwiftUI kennenzulernen. Als solches möchte ich, dass der primäre Klick (normalerweise LMB) "gräbt" (zeigt an, ob sich dort eine Mine befindet) und der sekundäre Klick (normalerweise RMB), um eine Flagge zu platzieren.

Ich habe das Graben arbeiten! Aber ich kann nicht herausfinden, wie man eine Flagge platziert, weil ich nicht herausfinden kann, wie man einen sekundären Klick erkennt.

Folgendes versuche ich :

BoardSquareView(
    style: self.style(for: square),
    model: square
)
.gesture(TapGesture().modifiers(.control).onEnded(self.handleUserDidAltTap(square)))
.gesture(TapGesture().onEnded(self.handleUserDidTap(square)))

Wie ich bereits angedeutet habe, wird die von zurückgegebene Funktion handleUserDidTapbeim Klicken ordnungsgemäß aufgerufen , die von zurückgegebene Funktion handleUserDidAltTapwird jedoch nur aufgerufen, wenn ich die Steuertaste gedrückt halte. Das ist sinnvoll, weil der Code dies sagt ... aber ich sehe keine API, die dazu führen könnte, dass sekundäre Klicks registriert werden, sodass ich nicht weiß, was ich sonst tun soll.

Ich habe es auch versucht, aber das Verhalten schien identisch zu sein:

BoardSquareView(
    style: self.style(for: square),
    model: square
)
.gesture(TapGesture().modifiers(.control).onEnded(self.handleUserDidAltTap(square)))
.onTapGesture(self.handleUserDidTap(square))

1
Dein erster Link ist kaputt. Privates Repo?
Gil Birman

.onTapGesture() Hör zu.
Raymond

Hoppla, du hast recht @GilBirman! Fest; Entschuldigung
Ben Leggiero

@ Raymond Ich habe das zuerst versucht. Wenn ich nichts Großes vermisse, scheint es sich identisch zu verhalten.gesture(TapGesture().onEnded(.......))
Ben Leggiero

Antworten:


4

Nach dem derzeitigen Stand von SwiftUI ist dies nicht direkt möglich. Ich bin mir sicher, dass dies in Zukunft der Fall sein wird, aber im Moment TapGesturekonzentriert sich das eindeutig hauptsächlich auf die iOS-Anwendungsfälle, bei denen kein "Rechtsklick" vorliegt. Ich denke, dies wurde deshalb ignoriert. Beachten Sie, dass das Konzept der "langen Presse" ein erstklassiger Bürger in Form von LongPressGestureist und fast ausschließlich in einem iOS-Kontext verwendet wird, der diese Theorie unterstützt.

Trotzdem habe ich einen Weg gefunden, um diese Arbeit zu machen. Sie müssen lediglich auf die ältere Technologie zurückgreifen und diese in Ihre SwiftUI-Ansicht einbetten.

struct RightClickableSwiftUIView: NSViewRepresentable {
    func updateNSView(_ nsView: RightClickableView, context: NSViewRepresentableContext<RightClickableSwiftUIView>) {
        print("Update")
    }

    func makeNSView(context: Context) -> RightClickableView {
        RightClickableView()
    }

}

class RightClickableView : NSView {
    override func mouseDown(with theEvent: NSEvent) {
        print("left mouse")
    }

    override func rightMouseDown(with theEvent: NSEvent) {
        print("right mouse")
    }
}

Ich habe dies getestet und es hat bei mir in einer ziemlich komplexen SwiftUI-Anwendung funktioniert. Der grundlegende Ansatz hier ist:

  1. Erstellen Sie Ihre Hörkomponente als NSView.
  2. Schließen Sie es mit einer SwiftUI-Ansicht ein, die implementiert wird NSViewRepresentable .
  3. Fügen Sie Ihre Implementierung in die Benutzeroberfläche ein, wo Sie sie möchten, genau wie bei jeder anderen SwiftUI-Ansicht.

Keine ideale Lösung, aber für den Moment vielleicht gut genug. Ich hoffe, dies löst Ihr Problem, bis Apple die Funktionen von SwiftUI weiter erweitert.


Vielen Dank. Das ist im Grunde das, was ich jetzt gemacht habe . Wirklich traurig, dass dies ihr erster Eindruck mit dem Framework ist. Ich werde dies als akzeptiert markieren, bis (hoffentlich 🤞🏼) eine bessere Lösung kommt
Ben Leggiero

1
Welp; sieht so aus, als wäre dies heute die beste Antwort. Das Kopfgeld gehört dir! Hoffentlich haben wir eines Tages eine offizielle Lösung.
Ben Leggiero
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.