Swift NSViewController响应mouseDown事件,但不响应keyDown事件 [英] Swift NSViewController responds to mouseDown event, but not keyDown event
问题描述
我正在尝试使用Swift和Cocoa为OS X创建一个应用程序。我希望应用程序对关键事件做出响应,而焦点不在文本字段上/中。我在Xcode中使用情节提要创建了一个新的Cocoa项目,并将ViewController.swift类修改为以下内容:
I am trying to create an application for OS X using Swift and Cocoa. I want the application to respond to key events without the focus being on/in a text field. I created a new Cocoa project with storyboards in Xcode, and have modified the ViewController.swift class to the following:
import Cocoa
class ViewController: NSViewController {
override func mouseDown(theEvent: NSEvent) {
println( "Mouse Clicked" )
}
override func keyDown(theEvent: NSEvent) {
println( "Key Pressed" )
}
override func viewDidLoad() {
super.viewDidLoad()
}
override var representedObject: AnyObject? {
didSet {
}
}
}
运行该程序时,单击窗口会得到控制台输出,但是按任何键都不会得到任何控制台输出。
When I run the program, I get console output when I click on the window, but I don't get any console output when I press any keys.
所以我的问题是:为什么我的程序为什么响应鼠标事件而不响应键事件?我需要做什么额外的步骤才能使键事件像鼠标事件一样起作用?
看来,自从我的视图控制器进入响应者链以来,它拦截了鼠标事件,所以这似乎不是问题。我在SE上找到了其他答案,说我需要子类化NSView或NSWindow类。
It appears that my view controller is in the responder chain since it intercepts the mouse events, so that doesn't seem to be the problem. I have found other answers on here on SE saying I need to subclass the NSView or NSWindow class. Is it possible to get key events without doing that?
预先感谢。
编辑:除了可接受的答案 Swift-从NSViewController捕获keydown 是一个很好的解决方案。
In addition to the accepted answer, Swift - Capture keydown from NSViewController is a great, clear solution.
推荐答案
您观察到的差异源自以下事实:可可在处理鼠标事件和键盘事件方面有些不同。在事件分派过程的早期,所有事件都会由系统发送到 NSWindow
对象。对于鼠标事件, NSWindow
将其转发到用户单击的视图;对于键盘事件, NSWindow
会将其转发到当前键窗口的第一响应者。
The difference you observed originates from the fact that Cocoa handles mouse events and keyboard events somewhat differently. In early stage of the event dispatching process, all events are sent to the NSWindow
object by system. For mouse events, NSWindow
forwards them to the view on which user clicked; for keyboard events, NSWindow
will forward them to the first responder of current key window.
NSWindow
的最初的第一响应者是窗口本身。当用户单击 NSView
时, NSWindow
会尝试使该视图成为第一个响应者通过发送 acceptsFirstResponder
消息。如果返回 YES
,则单击的视图将成为第一响应者。
The initial first responder of an NSWindow
is the window itself. When user clicks on an NSView
, NSWindow
will try to make that view the first responder by sending an acceptsFirstResponder
message. If it returns YES
, the clicked view will become first responder.
陷阱是默认情况下, acceptsFirstResponder
返回 NO
。普通的 NSView
不会成为第一响应者,因此不会接收键盘事件。因此,最简单的解决方案是将您的 NSView
子类化,重写 acceptsFirstResponder
以返回 YES
。
The "gotcha," however, is that acceptsFirstResponder
returns NO
by default. As a plain NSView
won't become the first responder, it won't receive keyboard events. So the easiest solution is to subclass your NSView
, override acceptsFirstResponder
to return YES
.
这篇关于Swift NSViewController响应mouseDown事件,但不响应keyDown事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!