swift - 有没有办法在用户按住鼠标按钮时接收 macOS 事件?
问题描述
拥有一个 SwiftUI slider
。用户继续拖动它。在拖动的同时,用户也按下了Option
键。
我想根据键盘修饰符标志更改(例如选项键)更改用户界面。但是,在拖动滑块甚至按下鼠标按钮时,似乎主事件循环被阻塞了。
当使用NSEvent.addLocalMonitorForEvents(mathing:handler)
来获取Option
按键通知时,处理程序甚至不会在用户拖动滑块时被调用。
有什么办法可以实现吗?
我也很想了解为什么问题首先存在。
解决方案
最终,我最终使用了一个计时器块来检查和发布键盘修饰符标志的更改。
import Cocoa
import Combine
/**
Publishers for keyboard events.
The modifiers are checked regularly by a Timer running on the Main `RunLoop` in `.common` mode
to ensure the modifiers are detected even when having mouse button pressed down
(which normally blocks the run loops on the main thread which are not in `common` mode).
The `NSEvent.addLocalMonitorForEvents` cannot be used because the handler is not executed
for nested-tracking loops, such as control tracking (e.g. when a mouse button is down).
*/
public class KeyboardEvents {
/// Broadcasts keyboard flag changes (e.g. keys like Option, Command, Control, Shift, etc.)
public let modifierFlagsPublisher: AnyPublisher<NSEvent.ModifierFlags?, Never>
private let modifierFlagsSubject = PassthroughSubject<NSEvent.ModifierFlags?, Never>()
private var timer: Timer!
public init() {
modifierFlagsPublisher = modifierFlagsSubject.removeDuplicates().eraseToAnyPublisher()
timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { [unowned self] _ in
modifierFlagsSubject.send(NSApp.currentEvent?.modifierFlags)
}
RunLoop.current.add(timer, forMode: .common)
}
deinit {
timer.invalidate()
}
}
推荐阅读
- android - 将 OnItemLongClickListener 添加到 groupie 回收站视图
- python - 不使用 graphviz/web 可视化决策树
- php - Laravel:用 eloquent 获取最常用的词
- python - 将多个json文件合并到一个json文件中
- java - SonarQube 报告具有不同参数的相同方法调用的重复代码
- generics - 如果它包含一个字符串,我如何编写一个接受通用枚举并打印它的函数?
- ag-grid - AG Grid - 访问 GridApi 的最佳方式
- jenkins - 如果下游作业失败,如何使主 Jenkins 管道作业失败
- css - 在引导切换开关顶部对齐标签
- java - 将 Struts 1.x 迁移到什么?