Cocoa 未在自定义ViewController或View上调用向下键(带:),仅在WindowController上调用
我已经将我的非基于文档的macOS应用程序的大部分核心功能移到了一个定制的嵌入式框架中 应用程序代码有一个带有初始窗口的标准主情节提要,该窗口有一个“窗口内容”关系/转换为指向嵌入框架内情节提要的情节提要引用。其中有一个自定义的Cocoa 未在自定义ViewController或View上调用向下键(带:),仅在WindowController上调用,cocoa,nsview,xcode-storyboard,nswindowcontroller,keyboard-input,Cocoa,Nsview,Xcode Storyboard,Nswindowcontroller,Keyboard Input,我已经将我的非基于文档的macOS应用程序的大部分核心功能移到了一个定制的嵌入式框架中 应用程序代码有一个带有初始窗口的标准主情节提要,该窗口有一个“窗口内容”关系/转换为指向嵌入框架内情节提要的情节提要引用。其中有一个自定义的NSViewController子类和一个自定义的NSView子类 我想在框架内对所有输入事件处理代码进行分组,这意味着在自定义的NSView子类上实现mouseDown(with:),瞧,当我在应用程序窗口内单击时,它会被调用。到目前为止,一切顺利 接下来,我实现了ke
NSViewController
子类和一个自定义的NSView
子类
我想在框架内对所有输入事件处理代码进行分组,这意味着在自定义的NSView
子类上实现mouseDown(with:)
,瞧,当我在应用程序窗口内单击时,它会被调用。到目前为止,一切顺利
接下来,我实现了keyDown(使用:)
来类似地处理键盘输入。但是,在运行时,它不会被调用,相反,我会听到恼人的嘟嘟声(NSBeep
)
我尝试在视图控制器上实现keyDown(使用:)
,但都是一样的
最后,我尝试在我的NSWindowController
子类上实现密钥处理程序,这确实有效
因此,我可以通过如下方式转发事件来解决此问题:
class WindowController: NSWindowController {
override func keyDown(with event: NSEvent) {
contentViewController?.view.keyDown(with: event)
}
}
,但这是非常不雅的。我宁愿不要用输入逻辑污染应用程序代码
然而,这似乎与嵌入框架无关。从“Cocoa App”模板中,并确认只有在窗口控制器代码上实现时才会调用keyDown(with:)
,而不是在视图或视图控制器端
在基于情节提要的应用程序中,如何在视图或视图控制器(而不是窗口或窗口控制器)上调用键下键(使用:)
?(这样我就可以将其从主应用程序移到嵌入式框架中)
编辑:问题已标记为重复。我尝试了回答另一个问题时指出的解决方案(即,重写
acceptsFirstResponder
以返回true
)。这解决了我的最小演示项目中的问题,但当我在我的完整应用程序上尝试时,它仍然不起作用(在发布此问题之前,我确实看到了这个问题,并尝试在我的应用程序中覆盖acceptsFirstResponder
)
我现在将尝试修改我的最小poject,看看是否可以在主应用程序中报告该问题
编辑2:我已将最小项目重构为:
编辑3:我无法在最小项目上重现该问题。 在我的应用程序的自定义视图中,我实现了:
public override var acceptsFirstResponder: Bool {
return true
}
public override func performKeyEquivalent(with event: NSEvent) -> Bool {
let retVal = super.performKeyEquivalent(with: event)
return retVal
}
acceptsFirstResponder
被调用两次李>
performKeyEquivalent(with:)
也会被调用两次。检查上面的中间变量retVal
,可以发现超类的实现总是返回false
。从该方法返回后,将调用NSBeep()
,而keyDown(with:)
不会被调用true
,而不是super.performKeyEquivalent(with:)
,我可以避免调用NSBeep()
(但是keyDown(with:)
仍然没有调用…)编辑4(最终版): 出于绝望,我清除了应用程序主情节提要中窗口控制器的身份检查器的“自定义类”字段(默认为
NSWindowController
)
突然,我的自定义视图的向下键(带:)
开始被调用
我恢复了自定义类以进行确认
它仍然有效
我清理生成文件夹并重试
它仍然有效
现在,即使在我的主应用程序上,我也无法再重现这个问题。我真的不知道该说什么……按键事件被发送给第一响应者。查看@Willeke的可能副本查看我的编辑。按键事件发送给第一响应者。查看@Willeke的可能副本查看我的编辑。