我正在制作一个"LearnToTypeQuick“应用程序,因此我需要验证我的键盘按键,看看它们是否与我在view上打印的内容相匹配。
我想在我的keyDown中使用ViewController事件,因此我需要ViewController成为第一个响应者。
我的问题是:我该怎么做?
发布于 2015-03-22 18:38:28
我想在我的keyDown中使用ViewController事件,因此我需要ViewController成为第一个响应者。
你可能真的不需要那个。响应链的全部要点是,如果一个响应者不处理给定的消息,它会将消息传递给链中的下一个响应者,依此类推。所以,您真正需要的是在响应链中拥有视图控制器,并确保前面的任何响应者不处理您感兴趣的消息。
当然,另一种策略是将键处理代码移动到适当的视图中,并让该视图根据需要将消息发送给委托(该委托可以是视图控制器)。这可以在更新用户正在键入的视图等方面为您节省一些工作,而且它可能会更符合典型的应用程序设计。
这个策略的一个非常简单的实现就是让用户类型变成一个普通的旧NSTextView。许多打字程序向用户显示一些段落,并让用户将文章输入到某种文本编辑字段中。可以将视图控制器设置为文本字段的委托。NSTextView提供的委托消息之一是-textDidChange:,因此您可以在视图控制器中实现它(以及在视图控制器声明中采用NSTextViewDelegate协议)。如果然后将视图控制器设置为文本视图的委托,则每次视图中的文本发生更改时,文本视图都会发送-textDidChange:消息。然后,您可以将视图中的文本与模型文本进行比较,并突出显示任何不匹配的地方,这样用户就可以看到他/她犯了错误。
如果您真的希望您的视图控制器成为第一个响应者,没有什么可以阻止您这样做。您可以重写-acceptsFirstResponder,使其返回YES,然后向视图控制器发送-becomeFirstResponder消息。
发布于 2018-05-11 15:42:56
AppKit将窗口的initialFirstResponder放在响应链的前面,因为initialFirstResponder不是NSResponder,而是NSView,所以除非AppKit在这方面改变策略(这是不可能的),否则就不可能让NSViewController成为第一响应者。
如果您的窗口的contentView是一个普通的NSView (它不实现任何响应回调),那么事件就会传播到您的视图控制器。当操作系统提供的视图确实响应(因此是燕子)响应器回调(如SCNView或SKView )时,就会遇到麻烦。
在这种情况下,要将事件传递给视图控制器,您可以做的是子类后一个视图,覆盖感兴趣的响应程序方法,并将它们转发给nextResponder。
我不同意你的观点,凯勒:
"...make确信,在此之前的任何回复者都不会处理您感兴趣的消息。“
这要求您对子类进行子类处理,这不是理想的解决方案。我不认为这是“反应链的全部目的,”如你所说。
例如,UIWindow不使用(视图类型或任何类型的) initialFirstRespnoder,因此iOS不会受到这种不直观的限制。
此外,initialFirstResponder是get/set属性,但是,将其设置为0,同时将主窗口及其NSWindowController的nextResponder设置为视图控制器,仍然不会从响应者链中获得顽固的视图(例如,SKView或SCNView )。如果它是某种错误,我提交了错误报告#39575165。
https://stackoverflow.com/questions/29197751
复制相似问题