斯威夫特 3:
我需要这个,但是是动态的。这有点长,但很值得(恕我直言)。
所以我决定仅在命令键按下时启用此功能。这是通过在委托中注册本地密钥处理程序来实现的:
// MARK:- Local key monitor
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) {
// Watch local keys for window movenment, etc.
localKeyDownMonitor = NSEvent.addLocalMonitorForEvents(matching: NSEventMask.flagsChanged) { (event) -> NSEvent? in
return self.keyDownMonitor(event: event) ? nil : event
}
}
及其移除
func applicationWillTerminate(_ aNotification: Notification) {
// Forget key down monitoring
NSEvent.removeMonitor(localKeyDownMonitor!)
}
请注意,当 commandKeyDown 值被按键处理程序更改时。 didset{} 捕获此值更改以发布通知。此通知由您希望移动其窗口的任何视图注册 - 即在视图委托中
override func viewDidLoad() {
super.viewDidLoad()
// Watch command key changes
NotificationCenter.default.addObserver(
self,
selector: #selector(ViewController.commandKeyDown(_:)),
name: NSNotification.Name(rawValue: "commandKeyDown"),
object: nil)
}
并在viewWillDisappear()(委托)或窗口控制器windowShouldClose()时丢弃;添加这个
<your-view>.removeObserver(self, forKeyPath: "commandKeyDown")
所以顺序是这样的:
- 按键按下/释放
- 处理程序调用
- 已发布通知
视图的窗口 isMovableByWindowBackground 属性由通知更改 - 放置在视图控制器/委托或您注册观察者的位置。
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 中查看它的实际效果。