Отслеживание нажатия клавиш в 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
  }

0 ответов

Другие вопросы по тегам