Как я могу обнаружить щелчок правой кнопкой мыши в SwiftUI?

10

Я пишу простое приложение Mines, чтобы помочь мне узнать SwiftUI. Поэтому я хочу, чтобы первичный щелчок (обычно ЛКМ) «копал» (показывает, есть ли там мина), и вторичный щелчок (обычно юань), чтобы установить флаг.

У меня копание работает! Но я не могу понять, как разместить флаг, потому что я не могу понять, как обнаружить вторичный щелчок.

Вот что я пытаюсь :

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.

BT
источник
Спасибо. Это в основном то, что я делал сейчас . Очень грустно, что это их первое впечатление от рамок. Я буду отмечать это как принятое, пока (надеюсь, hope) не будет найдено лучшее решение
Бен Легжеро
1
Welp; Похоже, это лучший ответ сегодня. Щедрость твоя! Надеюсь, когда-нибудь у нас будет официальное решение.
Бен Легжеро