Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macos Swift-从NSViewController捕获按键_Macos_Swift - Fatal编程技术网

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
      }
   }
}