Make NSView in NSPanel first responder without key

2019-02-10 08:05发布

Is it possible to give an NSView inside an NSPanel first responder status without giving the NSPanel key window status (making the main application window resign key)?

Thanks.

1条回答
等我变得足够好
2楼-- · 2019-02-10 08:35

Well, I ended up figuring this one out, but it took a lot of research so I'll post the details here in case anyone else runs into the same problem. First of all, a few basics:

  1. It's impossible to have 2 windows actually be key at the same time
  2. It's possible to fake a window into thinking it's key by overriding -isKeyWindow but that won't give the views contained in the window first responder status.

My Scenario:

I added a child window containing an NSTableView into my main application window (the reason is irrelavant). The child window was an NSPanel with NSBorderlessWindowMask. I wanted to give the NSTableView first responder status without making the panel the key window because it took away focus from the main window (and the whole point of the child window illusion was to make the child window look like it was part of the main window).

The first thing I tried was fooling the table view into thinking that it was inside the key window by overriding isKeyWindow to return YES. This made the table view draw as if it were the first responder, but still did not give it first responder status.

The Solution:

So by default, NSBorderlessWindowMask will not allow the window to become key. To make the table view first responder, the window had to be key so I overrode canBecomeKeyWindow in the borderless window subclass to return YES. This, of course, took away key status from the main window, which was one of the things I wanted to avoid. To fix this, I subclassed my main window and overrode the following methods:

- (BOOL)isMainWindow
{
    return YES;
}

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

This subclass checks if the application is active, and if it is, it always returns YES so that no matter what window is active in your application, the main window will always behave as if it is still key. This sort of gives the illusion that you can have multiple windows be key at the same time and enables you to shift key window status to another window without losing it on your main window. Hope this helps!

查看更多
登录 后发表回答