NSWindow 在关闭 NSPopover 后失去了第一响应者

NSWindow loses first responder after dismissing NSPopover

我有一个 window,它显示一个带有一堆文本字段的弹出窗口。我希望这些文本字段是可制表的,但在弹出窗口出现时不聚焦。为了实现这一点,我在弹出窗口出现时将第一响应者设置为 nil

// Inside popover's view controller.
override func viewDidAppear() {
    self.view.window!.makeFirstResponder(nil)
}

直到弹出窗口被关闭导致拥有 window 第一响应者被设置为 window 本身,而不是弹出窗口出现之前的第一响应者的视图.但是,如果我在上面的块中执行 self.view.window!.makeFirstResponder(self.view) 或根本不触摸第一响应者,一切都会按预期工作,并且当弹出窗口被关闭时,拥有 window 的第一响应者会正确恢复。

据我所知,弹出窗口内部的更改不应影响拥有 window,因为弹出窗口拥有自己的 windows 和自己的响应链。

我很好奇幕后发生了什么。很确定这归结为响应者链的工作方式和更新方式,但我无法将这些点联系起来。

–––

谁能解释为什么当弹出窗口被关闭时,将弹出窗口内的第一响应者更改为 nil 会弄乱拥有 window 的(显示在其上方的)第一响应者?使用上述解决方法时不会影响它吗?

弹出窗口 window 是拥有者 window 的子对象 window 并与其父对象共享第一响应者。当弹出框关闭时 _NSPopoverCloseAndAnimate: 被调用。如果弹出窗口的第一响应者是 NSView 的子类,那么 _updateFirstResponderForIgnoredChildWindow: 将在拥有的 window 上调用,并且它将设置第一响应者。如果弹出窗口的第一响应者是 window,则不会恢复拥有 window 的第一响应者。

如果弹出窗口不包含任何可以成为第一响应者的视图,那么拥有 window 的文本字段将保持第一响应者并接受按键。