Swift 3:
我需要动态设置。这可能有点长,但值得(在我看来)。
因此,我决定仅在按下命令键时启用它。这是通过在委托中注册本地键处理程序来实现的:
var localKeyDownMonitor : Any? = nil
var commandKeyDown : Bool = false {
didSet {
let notif = Notification(name: Notification.Name(rawValue: "commandKeyDown"),
object: NSNumber(booleanLiteral: commandKeyDown))
NotificationCenter.default.post(notif)
}
}
func keyDownMonitor(event: NSEvent) -> Bool {
switch event.modifierFlags.intersection(.deviceIndependentFlagsMask) {
case [.command]:
self.commandKeyDown = true
return true
default:
self.commandKeyDown = false
return false
}
}
这是在委托启动时启用的:
func applicationDidFinishLaunching(_ aNotification: Notification) {
localKeyDownMonitor = NSEvent.addLocalMonitorForEvents(matching: NSEventMask.flagsChanged) { (event) -> NSEvent? in
return self.keyDownMonitor(event: event) ? nil : event
}
}
以及它的移除
func applicationWillTerminate(_ aNotification: Notification) {
NSEvent.removeMonitor(localKeyDownMonitor!)
}
注意,当键盘按下事件处理程序改变commandKeyDown值时。这个值的改变被didset{}捕获以发布通知。此通知由您希望其窗口移动的任何视图注册 - 即在视图代理中。
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(
self,
selector: #selector(ViewController.commandKeyDown(_:)),
name: NSNotification.Name(rawValue: "commandKeyDown"),
object: nil)
}
并在viewWillDisappear()(委托)或窗口控制器windowShouldClose()时丢弃;添加此内容
<your-view>.removeObserver(self, forKeyPath: "commandKeyDown")
所以顺序如下:
- 按键按下/释放
- 处理程序被调用
- 通知被发布
视图的window属性是否可通过窗口背景移动由通知更改 - 该通知位于视图控制器/代理或您注册观察者的位置。
internal func commandKeyDown(_ notification : Notification) {
let commandKeyDown : NSNumber = notification.object as! NSNumber
if let window = self.view.window {
window.isMovableByWindowBackground = commandKeyDown.boolValue
Swift.print(String(format: "command %@", commandKeyDown.boolValue ? "v" : "^"))
}
}
当你满意时,请删除跟踪器输出。在 GitHub 上的 SimpleViewer 中可以看到它的实际效果。