【问题标题】:Why does an NSWindow or NSView instance handle its own key events, and not its delegate?为什么 NSWindow 或 NSView 实例处理它自己的键事件,而不是它的委托?
【发布时间】:2009-06-20 20:22:52
【问题描述】:

作为 Cocoa 的新手,我很难理解为什么通用 NSResponder 子类会以它们看起来的方式实现关键事件。

在我的程序中,我有一个 NSWindow 子类,它占据了整个屏幕,并且必须处理关键事件。有几个主要的命令可以改变程序的整个状态(例如,当用户按下空格键时暂停计时器),像 NSTextField 句柄这样的子视图是没有意义的。

在我看来,委托(控制器)应该得到这些事件。相反,我发现我必须编写一堆凌乱的胶水代码让窗口(通过其keyDown:interpretKeyEvents: 选择器)通知控制器,或者我必须将一堆控制器代码移动到 NSWindow 子类自己。

这很混乱,我的直觉告诉我我错过了一些东西。有更清洁的解决方案吗?

【问题讨论】:

    标签: objective-c cocoa


    【解决方案1】:

    如果您设置正确,NSWindow 的代表将收到消息。 Cocoa 使用响应者链来转发来自第一响应者的消息——关键消息的关键视图,以及被点击/悬停/等的视图。对于鼠标消息——通过超级视图返回,向上通过窗口,最终到达窗口的委托。在Apple's site 上有一个很好的典型响应者链图。

    你真的不应该继承NSWindow,除非你正在实现一些花哨的窗口绘图或其他类似的东西。 Cocoa 提供了NSWindowController 类来充当窗口及其内容的控制器。

    通常的模式是继承NSWindowController 并将IBOutlets 添加到其中,然后使用NIB 来布置窗口内容。您将 NSWindowController 子类设置为 Interface Builder 中文件所有者代理的类。您还将窗口的delegate 分配给窗口控制器,以便它可以成为响应者链的一部分。最后,要创建窗口,您可以使用NSWindowControllerinitWithWindowNibName: 方法,该方法会自动加载NIB,并将新的窗口控制器作为文件的所有者。

    我建议阅读 Cocoa 文档中的窗口控制器,因为它们提供了您正在寻找的缺失链接。

    【讨论】:

    • 我的委托实际上是一个 NSWindowController 子类。我没有使用 Interface Builder,因为我正在尝试创建一个在其实例化时可能是无边界的窗口,也可能不是无边界的,而 IB 似乎不允许这样做——此外,我正在尝试了解详细信息,而且 IB 隐藏了很多东西,所以我认为对于这个应用程序,值得“艰难地”学习。感谢您提供指向文档该部分的链接。我读过它,但错过了关于 NSWindowController 作为最后手段的细节。显然我在管理响应者链时犯了一些错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-16
    • 2013-08-11
    • 1970-01-01
    • 2014-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多