web-dev-qa-db-fra.com

Comment puis-je détecter un clic droit dans SwiftUI?

J'écris ne simple application Mines pour m'aider à connaître SwiftUI. En tant que tel, je veux que le clic principal (généralement LMB) "Dig" (révèle s'il y a une mine là-bas), et un clic secondaire (généralement RMB) pour placer un drapeau.

J'ai le travail de creusage! Mais je ne peux pas comprendre comment placer un indicateur, car je ne peux pas comprendre comment détecter un clic secondaire.

Voici ce que j'essaye :

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

Comme je l'ai laissé entendre plus haut, la fonction renvoyée par handleUserDidTap est appelée correctement au clic, mais celle renvoyée par handleUserDidAltTap n'est appelée que lorsque je maintiens la touche Ctrl enfoncée. C'est logique parce que c'est ce que dit le code ... mais je ne vois aucune API qui pourrait lui permettre d'enregistrer des clics secondaires, donc je ne sais pas quoi faire d'autre.

J'ai également essayé cela, mais le comportement semblait identique:

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

En l'état actuel des choses avec SwiftUI, ce n'est pas directement possible. Je suis sûr que ce sera à l'avenir, mais pour le moment, le TapGesture est clairement axé principalement sur les cas d'utilisation iOS qui n'ont pas un concept de "clic droit", donc je pense que c'est pourquoi cela a été ignoré. Remarquez que le concept de "presse longue" est un citoyen de première classe sous la forme de LongPressGesture, et qui est presque exclusivement utilisé dans un contexte iOS, qui prend en charge cette théorie.

Cela dit, j'ai trouvé un moyen de faire fonctionner cela. Ce que vous devez faire, c'est vous replier sur l'ancienne technologie et l'intégrer dans votre vue SwiftUI.

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")
    }
}

J'ai testé cela, et cela a fonctionné pour moi dans une application SwiftUI assez complexe. L'approche de base ici est:

  1. Créez votre composant d'écoute en tant que NSView.
  2. Enveloppez-le avec une vue SwiftUI qui implémente NSViewRepresentable.
  3. Plop votre implémentation dans l'interface utilisateur où vous le souhaitez, comme vous le feriez avec n'importe quelle autre vue SwiftUI.

Ce n'est pas une solution idéale, mais cela pourrait être suffisant pour le moment. J'espère que cela résout votre problème jusqu'à ce que Apple étend encore les capacités de SwiftUI.

4
B.T.