在没有关键窗口状态的NSPanel第一响应者中创建NSView

时间:2011-02-06 21:04:02

标签: cocoa nsview nswindow nsresponder nspanel

是否可以在NSPanel第一响应者状态内提供NSView而不提供NSPanel密钥窗口状态(使主应用程序窗口重新签名密钥)?

感谢。

1 个答案:

答案 0 :(得分:8)

好吧,我最终想出了这个,但是我花了很多研究所以我会在这里发布详细信息以防其他人遇到同样的问题。首先,一些基础知识:

  1. 实际上不可能同时拥有2个窗口
  2. 可以通过覆盖-isKeyWindow伪造一个窗口来认为它是关键,但是这不会给窗口第一响应者状态中包含的视图。
  3. 我的情景:

    我在主应用程序窗口中添加了一个包含NSTableView的子窗口(原因是无关紧要)。子窗口为NSPanel NSBorderlessWindowMask。我想给出NSTableView第一响应者状态而不将面板作为关键窗口,因为它从主窗口中取走了焦点(并且子窗口错觉的整个点是让子窗口看起来像是它的一部分主窗口)。

    我尝试的第一件事就是通过覆盖isKeyWindow来返回YES来欺骗表格视图,使其认为它位于关键窗口内部。这使得表视图绘制就好像它是第一个响应者,但仍然没有给它第一个响​​应者状态。

    解决方案:

    因此,默认情况下,NSBorderlessWindowMask不允许窗口成为键。要使表视图第一响应者,窗口必须是键,所以我覆盖无边框窗口子类中的canBecomeKeyWindow以返回YES。当然,这会从主窗口中取消关键状态,这是我想要避免的事情之一。为了解决这个问题,我将窗口子类化,并覆盖了以下方法:

    - (BOOL)isMainWindow
    {
        return YES;
    }
    
    - (BOOL)isKeyWindow
    {
        return ([NSApp isActive]) ? YES : [super isKeyWindow];
    }
    

    此子类检查应用程序是否处于活动状态,如果是,则它始终返回YES,这样无论应用程序中的哪个窗口处于活动状态,主窗口将始终表现为仍然是关键。这种方式给人一种错觉,即你可以同时拥有多个窗口,并且可以将关键窗口状态转换到另一个窗口而不会丢失它在主窗口上。希望这有帮助!