You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 15:05:15