Отслеживание нажатия клавиш в Meun/Picker в SwiftUI на MacOS
Я изучаю программирование SwiftUI, пытаясь дублировать основные функции в MacOS Finder.
Кнопка групп в окне Finder (скриншот ниже) поставила меня в тупик. Щелчок меню показывает параметры группы, а щелчок параметра показывает параметры сортировки. Я не могу понять, как это делается.
Мой основной код выглядит следующим образом:
Menu {
if NSEvent.modifierFlags.contains(.option) {
Picker(selection: viewSorts, label: EmptyView()) {
ForEach(viewSorts) { sort in
Text(sort.name).tag(sort)
}
}
.labelsHidden()
.pickerStyle(InlinePickerStyle())
} else {
Picker(selection: viewGroups, label: EmptyView()) {
ForEach(viewGroups) { group in
Text(group.name).tag(group)
}
.labelsHidden()
.pickerStyle(InlinePickerStyle())
}
} Label: {
Image(systemName: "square.grid.3x1.below.line.grid.1x2")
}
Однако это работаетNSEvent.modifierFlags.contains(.option)
никогда не оценивается как истина.
В этом посте есть два примера, которые я использовал, чтобы решить проблему:
С использованиемonTapGesture
сEventModifiers
:
@State private var showSort = false
Menu {
if showSort {
// ... show sort picker ...
} else {
// ... show group picker ...
}
} Label: {
Image(systemName: "square.grid.3x1.below.line.grid.1x2")
}
.gesture(TapGesture().modifiers(.option).onEnded {
showSort = true
})
.onTapGesture {
showSort = false
}
И еще один с использованием расширения CGKeyCode:
import CoreGraphics
extension CGKeyCode
{
static let kVK_Option : CGKeyCode = 0x3A
static let kVK_RightOption: CGKeyCode = 0x3D
var isPressed: Bool {
CGEventSource.keyState(.combinedSessionState, key: self)
}
static var optionKeyPressed: Bool {
return Self.kVK_Option.isPressed || Self.kVK_RightOption.isPressed
}
}
Menu {
if CGKeyCode.optionIsPressed {
// ... show sort picker ...
} else {
// ... show group picker ...
}
} Label: {
Image(systemName: "square.grid.3x1.below.line.grid.1x2")
}
И из этих двух постов ( 1, 2) addLocalMonitorForEvents:
@State private var showSort = false
Menu {
if showSort {
// ... show sort picker ...
} else {
// ... show group picker ...
}
} Label: {
Image(systemName: "square.grid.3x1.below.line.grid.1x2")
}
.onAppear() {
NSEvent.addLocalMonitorForEvents(matching: .keyDown) { (keyEvent) -> NSEvent? in
if keyEvent.modifierFlags == .option {
showSort = true
} else {
showSort = false
}
return keyEvent
}
}
Ответ, вероятно, смотрит мне в лицо, но я просто не могу его видеть! Спасибо за любую помощь!
ОБНОВЛЕНИЕ: onContinuousHover работает, но обновляется только при перемещении мыши по меню.
.onContinuousHover { _ in
showSort = NSEvent.modifierFlags.contains(.option) ? true : false
}
Но onTapGesture не работает
.onTapGesture {
showSort = NSEvent.modifierFlags.contains(.option) ? true : false
}