解雇NSPopover后,NSWindow失去了第一响应者

时间:2019-02-13 12:41:42

标签: swift appkit first-responder responder-chain

我有一个窗口,其中显示了带有一堆文本字段的弹出窗口。我希望这些文本字段是可选项,但在弹出窗口出现时不要集中精力。为此,我将在弹出窗口出现时将第一响应者设置为nil

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

这可以正常工作,直到弹出窗口消失为止,导致拥有窗口的第一响应者设置为窗口本身,而不是出现弹出窗口之前的第一响应者的视图。但是,如果我在上面的代码块中self.view.window!.makeFirstResponder(self.view)或根本不触摸第一响应者,则一切都会按预期进行,并且当弹出窗口被消除时,所属窗口的第一响应者将正确还原。

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

我很好奇幕后发生的事情。可以肯定的是,这取决于响应者链的工作方式并得到更新,但我无法说明问题。

–––

谁能解释为什么将弹出式窗口中的第一个响应者更改为nil会导致当弹出式窗口被解散时会弄乱所属窗口(在其上方显示)的第一响应者吗?使用上述解决方法时,它不会受到影响吗?

1 个答案:

答案 0 :(得分:2)

弹出窗口是拥有窗口的子窗口,并且与父窗口共享第一响应者。弹出窗口关闭时,将调用_NSPopoverCloseAndAnimate:。如果弹出窗口的第一响应者是NSView的子类,则在拥有的窗口上调用_updateFirstResponderForIgnoredChildWindow:,它将设置第一响应者。如果弹出窗口的第一响应者是一个窗口,则不会还原拥有窗口的第一响应者。

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