如何在SwiftUI macOS项目中用NSNotification观察修饰键(如Option、Shift)按下状态
监听Option按键状态实现SwiftUI视图更新
因为系统没有提供专门用于Option键状态变化的NSNotification,所以直接通过NSEvent全局事件监听是更直接的方案,结合Combine的@Published属性就能实时同步按键状态到SwiftUI视图。
实现步骤
1. 创建按键监听的ObservableObject类
这个类负责全局监听键盘事件,维护Option键的按下状态并通过@Published对外发送更新:
import Combine import SwiftUI import AppKit class KeyPressMonitor: ObservableObject { @Published var isOptionPressed = false private var eventMonitor: Any? init() { // 监听键盘按下和抬起事件 eventMonitor = NSEvent.addGlobalMonitorForEvents(matching: [.keyDown, .keyUp]) { [weak self] event in guard let self = self else { return } // 获取当前Option键的修饰状态 let currentOptionState = event.modifierFlags.contains(.option) // 状态变化时才更新,避免不必要的视图刷新 if self.isOptionPressed != currentOptionState { DispatchQueue.main.async { self.isOptionPressed = currentOptionState } } } } deinit { // 移除监听器,避免内存泄漏 if let monitor = eventMonitor { NSEvent.removeMonitor(monitor) } } }
2. 在SwiftUI视图中使用
通过@StateObject(iOS 14+/macOS 11+)或@ObservedObject绑定监听类,实时根据按键状态更新视图:
struct ContentView: View { @StateObject private var keyMonitor = KeyPressMonitor() var body: some View { Text(keyMonitor.isOptionPressed ? "Option键已按下" : "Option键未按下") .font(.title) .padding() } }
注意事项
- 全局事件监听仅在应用处于活跃状态时生效,后台运行时不会触发事件。
- 如果需要区分左/右Option键,可以通过
event.keyCode判断:左Option键的keyCode通常为58,右Option为61(不同系统版本可能有差异,建议自行测试确认)。 - 必须在
DispatchQueue.main中更新@Published属性,保证UI更新在主线程执行。
内容的提问来源于stack exchange,提问作者dark_alone
相关产品推荐
相关产品推荐

