¿Cómo puedo detectar un clic derecho en SwiftUI?

10

Estoy escribiendo una aplicación simple de Mines para ayudarme a conocer SwiftUI. Como tal, quiero que el clic primario (generalmente LMB) se "cave" (revele si hay una mina allí) y el clic secundario (generalmente RMB) para colocar una bandera.

Tengo la excavación trabajando! Pero no puedo entender cómo colocar una bandera, porque no puedo descubrir cómo detectar un clic secundario.

Esto es lo que estoy intentando :

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

Como implique anteriormente, la función devuelta por handleUserDidTapse llama correctamente al hacer clic, pero la que devuelve handleUserDidAltTapsolo se llama cuando mantengo presionada la tecla Control. Eso tiene sentido porque eso es lo que dice el código ... pero no veo ninguna API que pueda hacer que registre clics secundarios, por lo que no sé qué más hacer.

También probé esto, pero el comportamiento parecía idéntico:

BoardSquareView(
    style: self.style(for: square),
    model: square
)
.gesture(TapGesture().modifiers(.control).onEnded(self.handleUserDidAltTap(square)))
.onTapGesture(self.handleUserDidTap(square))
Ben Leggiero
fuente
1
Tu primer enlace está roto. Repo privado?
Gil Birman
.onTapGesture() Echale un vistazo.
Raymond
¡Vaya, tienes razón @GilBirman! Fijo; perdón por eso
Ben Leggiero
@ Raymond Intenté eso primero. A menos que me falte algo grande, parece comportarse de manera idéntica.gesture(TapGesture().onEnded(.......))
Ben Leggiero

Respuestas:

4

Tal como están las cosas con SwiftUI en este momento, esto no es directamente posible. Estoy seguro de que lo será en el futuro, pero en este momento, TapGestureestá claramente enfocado principalmente en los casos de uso de iOS que no tienen el concepto de "clic derecho", así que creo que es por eso que se ignoró. Tenga en cuenta que el concepto de "prensa larga" es un ciudadano de primera clase en la forma de LongPressGesture, y que se utiliza casi exclusivamente en un contexto de iOS, que respalda esta teoría.

Dicho esto, descubrí una manera de hacer que esto funcione. Lo que tiene que hacer es recurrir a la tecnología más antigua e integrarla en su vista 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")
    }
}

Probé esto, y funcionó para mí dentro de una aplicación SwiftUI bastante compleja. El enfoque básico aquí es:

  1. Crea tu componente de escucha como un NSView.
  2. Envuélvalo con una vista SwiftUI que implemente NSViewRepresentable.
  3. Coloque su implementación en la interfaz de usuario donde lo desee, tal como lo haría con cualquier otra vista de SwiftUI.

No es una solución ideal, pero podría ser lo suficientemente buena por ahora. Espero que esto resuelva su problema hasta que Apple expanda aún más las capacidades de SwiftUI.

BT
fuente
Gracias. Esto es básicamente lo que estaba haciendo por ahora . Realmente triste que esta sea su primera impresión con el marco. Marcaré esto como aceptado hasta que (con suerte 🤞🏼) aparezca una mejor solución
Ben Leggiero
1
Welp Parece que esta es la mejor respuesta hoy. ¡La recompensa es tuya! Esperemos que algún día tengamos una solución oficial.
Ben Leggiero