Як я можу виявити клацніть правою кнопкою миші у SwiftUI?


10

Я пишу простий додаток "Міни", щоб допомогти мені познайомитися зі SwiftUI. Тому я хочу, щоб первинний клік (як правило, LMB) "копав" (виявляв, чи є там шахта), а вторинний клацання (зазвичай RMB), щоб розмістити прапор.

У мене копання працює! Але я не можу зрозуміти, як розмістити прапор, тому що я не можу зрозуміти, як виявити вторинний клік.

Ось що я намагаюся :

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

Як я мав на увазі раніше, функція, що повертається, handleUserDidTapвикликається належним чином при натисканні, але функція , що повертається, handleUserDidAltTapвикликається лише тоді, коли я утримую клавішу Control. Це має сенс, тому що так пише код ... але я не бачу жодного API, який би міг змусити його реєструвати вторинні кліки, тому я не знаю, що робити ще.

Я також спробував це, але поведінка здавалася ідентичною:

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

1
Ваше перше посилання розірвано. Приватне репо?
Гіл Бірман

.onTapGesture() Перевір.
Реймонд

Ну, ти правий @GilBirman! Виправлено; вибачте з цього приводу
Бен Леджіеро

@Raymond Я спробував це першим. Якщо я не пропускаю щось велике, то, схоже, поводиться ідентично.gesture(TapGesture().onEnded(.......))
Бен Лег'єро

Відповіді:


4

Оскільки зараз із SwiftUI все стоїть, це прямо не можливо. Я впевнений, що це буде в майбутньому, але на даний момент, TapGestureчітко орієнтований головним чином на випадки використання iOS, які не мають поняття "клацання правою кнопкою миші", тому я думаю, що саме тому це було проігноровано. Зауважте, що концепція "тривалої преси" є першокласним громадянином у формі LongPressGesture, і це майже виключно використовується в контексті iOS, що підтримує цю теорію.

Однак, я створив спосіб зробити цю роботу. Що вам потрібно зробити, це повернутись на старіші технології та вбудувати її у свій погляд 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")
    }
}

Я перевірив це, і він працював для мене у досить складному додатку SwiftUI. Основний підхід тут:

  1. Створити свій компонент прослуховування як NSView.
  2. Оберніть його з поданням SwiftUI, яке реалізується NSViewRepresentable.
  3. Перекладіть свою реалізацію в інтерфейс користувача там, де ви цього хочете, як і в будь-якому іншому представництві SwiftUI.

Не ідеальне рішення, але воно може бути досить хорошим зараз. Я сподіваюся, що це вирішить вашу проблему, поки Apple ще більше не розширить можливості SwiftUI.


Дякую. Це в основному те, що я зараз робив . Дуже сумно, що це їхнє перше враження від рамки. Я відзначу це як прийняте, поки (сподіваюсь 🤞🏼) не знайдеться кращого рішення
Бен Леджієро,

1
Welp; схоже, це найкраща відповідь сьогодні. Бонус за вами! Сподіваємось, колись у нас буде офіційне рішення.
Бен Леджієро
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.