Come posso rilevare un clic destro in SwiftUI?


10

Sto scrivendo una semplice app Mines per aiutarmi a conoscere SwiftUI. Come tale, voglio che il clic principale (di solito LMB) "scavi" (rivela se c'è una miniera lì) e il clic secondario (di solito RMB) per posizionare una bandiera.

Ho il lavoro di scavo! Ma non riesco a capire come posizionare una bandiera, perché non riesco a capire come rilevare un clic secondario.

Ecco cosa sto provando :

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

Come ho insinuato in precedenza, la funzione restituita da handleUserDidTapviene chiamata correttamente al clic, ma quella restituita handleUserDidAltTapviene chiamata solo quando si tiene premuto il tasto Control. Questo ha senso perché è quello che dice il codice ... ma non vedo alcuna API che possa far registrare i clic secondari, quindi non so cos'altro fare.

Ho anche provato questo, ma il comportamento sembrava identico:

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

1
Il tuo primo link è interrotto. Repo privato?
Gil Birman,

.onTapGesture() controlla.
Raymond,

Spiacenti, hai ragione @GilBirman! Fisso; scusatemi per questo
Ben Leggiero l'

@Raymond L'ho provato per primo. A meno che non mi manchi qualcosa di grosso, sembra comportarsi in modo identico a.gesture(TapGesture().onEnded(.......))
Ben Leggiero l'

Risposte:


4

Allo stato attuale di SwiftUI, questo non è direttamente possibile. Sono sicuro che lo sarà in futuro, ma al momento, TapGestureè chiaramente focalizzato principalmente sui casi d'uso iOS che non hanno il concetto di "clic con il tasto destro", quindi penso che sia per questo che è stato ignorato. Si noti che il concetto di "stampa lunga" è un cittadino di prima classe sotto forma di LongPressGesture, e che viene utilizzato quasi esclusivamente in un contesto iOS, che supporta questa teoria.

Detto questo, ho trovato un modo per farlo funzionare. Quello che devi fare è ripiegare sulla tecnologia precedente e incorporarla nella 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")
    }
}

Ho provato questo, e ha funzionato per me all'interno di un'applicazione SwiftUI abbastanza complessa. L'approccio di base qui è:

  1. Crea il tuo componente di ascolto come NSView.
  2. Avvolgilo con una vista SwiftUI che implementa NSViewRepresentable .
  3. Inserisci la tua implementazione nell'interfaccia utente dove desideri, proprio come faresti con qualsiasi altra vista SwiftUI.

Non è una soluzione ideale, ma potrebbe essere abbastanza buona per ora. Spero che questo risolva il tuo problema fino a quando Apple non espande ulteriormente le capacità di SwiftUI.


Grazie. Questo è fondamentalmente quello che stavo facendo per ora . Davvero triste che questa sia la loro prima impressione con il framework. Lo segnerò come accettato fino a quando (si spera 🤞🏼) arriva una soluzione migliore
Ben Leggiero,

1
Welp; sembra che questa sia la migliore risposta oggi. La taglia è tua! Spero che un giorno avremo una soluzione ufficiale.
Ben Leggiero,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.