Macos Swift-从NSViewController捕获按键
我想在我的小应用程序中捕获关键事件 我所做的:Macos Swift-从NSViewController捕获按键,macos,swift,Macos,Swift,我想在我的小应用程序中捕获关键事件 我所做的: class ViewController : NSViewController { ... override func keyDown(theEvent: NSEvent) { if theEvent.keyCode == 124 { println("abc") } else { println("abcd") } } overr
class ViewController : NSViewController {
...
override func keyDown(theEvent: NSEvent) {
if theEvent.keyCode == 124 {
println("abc")
} else {
println("abcd")
}
}
override var acceptsFirstResponder: Bool {
return true
}
override func becomeFirstResponder() -> Bool {
return true
}
override func resignFirstResponder() -> Bool {
return true
}
...
}
发生了什么:
class ViewController : NSViewController {
...
override func keyDown(theEvent: NSEvent) {
if theEvent.keyCode == 124 {
println("abc")
} else {
println("abcd")
}
}
override var acceptsFirstResponder: Bool {
return true
}
override func becomeFirstResponder() -> Bool {
return true
}
override func resignFirstResponder() -> Bool {
return true
}
...
}
按下一个键时,会播放Funk
音效
我看到很多帖子都在谈论这是一个如何属于
NSView
的委托,而NSViewController
没有访问权限。但是keydown
功能override
auto在类型为NSViewController
的类中完成,这让我相信这是错误的 Xcode 8.2.1•Swift 3.0.2
import Cocoa
class ViewController: NSViewController {
@IBOutlet var textField: NSTextField!
override func viewDidLoad() {
super.viewDidLoad()
NSEvent.addLocalMonitorForEvents(matching: .flagsChanged) {
self.flagsChanged(with: $0)
return $0
}
NSEvent.addLocalMonitorForEvents(matching: .keyDown) {
self.keyDown(with: $0)
return $0
}
}
override func keyDown(with event: NSEvent) {
switch event.modifierFlags.intersection(.deviceIndependentFlagsMask) {
case [.command] where event.characters == "l",
[.command, .shift] where event.characters == "l":
print("command-l or command-shift-l")
default:
break
}
textField.stringValue = "key = " + (event.charactersIgnoringModifiers
?? "")
textField.stringValue += "\ncharacter = " + (event.characters ?? "")
}
override func flagsChanged(with event: NSEvent) {
switch event.modifierFlags.intersection(.deviceIndependentFlagsMask) {
case [.shift]:
print("shift key is pressed")
case [.control]:
print("control key is pressed")
case [.option] :
print("option key is pressed")
case [.command]:
print("Command key is pressed")
case [.control, .shift]:
print("control-shift keys are pressed")
case [.option, .shift]:
print("option-shift keys are pressed")
case [.command, .shift]:
print("command-shift keys are pressed")
case [.control, .option]:
print("control-option keys are pressed")
case [.control, .command]:
print("control-command keys are pressed")
case [.option, .command]:
print("option-command keys are pressed")
case [.shift, .control, .option]:
print("shift-control-option keys are pressed")
case [.shift, .control, .command]:
print("shift-control-command keys are pressed")
case [.control, .option, .command]:
print("control-option-command keys are pressed")
case [.shift, .command, .option]:
print("shift-command-option keys are pressed")
case [.shift, .control, .option, .command]:
print("shift-control-option-command keys are pressed")
default:
print("no modifier keys are pressed")
}
}
}
要在按下要对视图进行子类化的字符键时消除咕噜声,请重写performKeyEquivalent方法并返回true
import Cocoa
class View: NSView {
override func performKeyEquivalent(with event: NSEvent) -> Bool {
return true
}
}
我从
NSWindowController的子类中设法让它工作
class MyWindowController: NSWindowController {
override func keyDown(theEvent: NSEvent) {
print("keyCode is \(theEvent.keyCode)")
}
}
更新:
import Cocoa
protocol WindowControllerDelegate {
func keyDown(aEvent: NSEvent)
}
class WindowController: NSWindowController {
var delegate: WindowControllerDelegate?
override func windowDidLoad() {
super.windowDidLoad()
delegate = window?.contentViewController as! ViewController
}
override func keyDown(theEvent: NSEvent) {
delegate?.keyDown(theEvent)
}
}
和视图控制器:
class ViewController: NSViewController, WindowControllerDelegate {
@IBOutlet weak var textField: NSTextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override var representedObject: AnyObject? {
didSet {
// Update the view, if already loaded.
}
}
override func keyDown(theEvent: NSEvent) {
textField.stringValue = "key = " + (theEvent.charactersIgnoringModifiers
?? "")
textField.stringValue += "\ncharacter = " + (theEvent.characters ?? "")
textField.stringValue += "\nmodifier = " + theEvent.modifierFlags.rawValue.description
}
}
我试图为swift 3找到答案,以下是对我有效的方法:
斯威夫特3
Swift4
刚刚为同样的问题找到了解决方案,Swift4。其背后的思想是:如果按键是由自定义逻辑处理的,则处理程序应返回nil,否则(未处理的)事件
我们现在的情况是:按下键时不会发出咕噜声/恐惧声
[更新]添加了对keyWindow的检查。如果没有此选项,即使另一个视图/窗口包含第一响应者,也会触发keyDown()。哪个对象是第一响应者?要消除“恐惧声音”,只需在闭包中返回nil而不是事件。我使用localMonitor方法。用这种方法消除恐惧声音的一个警告是,你不要将按键事件转发到应用程序的其他部分,如cmd+q,为了缓解这种情况,如果你想锁定a、b、b,你可以只在你想要锁定的按键事件上返回nil,c击键只在这些击键时返回nil,等等。签名在swift 4上发生了变化
override func keyDown(带有event:NSEvent){}
您如何判断您使用的是swift 1.2还是2.0这在swift 2.x中适用-我可以在override func keyDown()事件代码中获得keyDown事件,但我仍然得到“Funk”声音如何消除“Funk”声音?Leo Dabus-你是否建议我使用你的隐形按钮想法消除按键事件的“Funk”声音?我的窗口(视图)有几个“标签”字段(标签实际上只是NSTextFields).让我们来看看。这是帮助我摆脱咕噜声的唯一答案。有没有一种简单的方法可以检测长按(按住)键?
class MyViewController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
// ...
NSEvent.addLocalMonitorForEvents(matching: .keyDown) {
if self.myKeyDown(with: $0) {
return nil
} else {
return $0
}
}
}
func myKeyDown(with event: NSEvent) -> Bool {
// handle keyDown only if current window has focus, i.e. is keyWindow
guard let locWindow = self.view.window,
NSApplication.shared.keyWindow === locWindow else { return false }
switch Int( event.keyCode) {
case kVK_Escape:
// do what you want to do at "Escape"
return true
default:
return false
}
}
}