NSWindow 在关闭 NSPopover 后失去了第一响应者
Posted
技术标签:
【中文标题】NSWindow 在关闭 NSPopover 后失去了第一响应者【英文标题】:NSWindow loses first responder after dismissing NSPopover 【发布时间】:2019-02-13 12:41:41 【问题描述】:我有一个窗口,它显示一个带有一堆文本字段的弹出框。我希望这些文本字段在弹出框出现时是可选项卡但不集中的。为了实现这一点,我在弹出框出现时将第一响应者设置为nil
:
// Inside popover's view controller.
override func viewDidAppear()
self.view.window!.makeFirstResponder(nil)
这工作正常,直到弹出框被解除导致拥有窗口的第一响应者被设置为窗口本身,而不是在弹出框出现之前作为第一响应者的视图。但是,如果我在上面的块中执行 self.view.window!.makeFirstResponder(self.view)
或根本不触摸第一响应者,一切都会按预期工作,并且当弹出框被解除时,拥有窗口的第一响应者会正确恢复。
据我所知,popover 内部的变化不应该影响拥有的窗口,因为 popover 有自己的窗口和自己的响应者链。
我很好奇幕后发生了什么。很确定这取决于响应者链的工作方式和更新方式,但我无法连接这些点。
–––
谁能解释为什么当弹出框被解除时,将弹出框内的第一响应者更改为nil
会扰乱拥有窗口(在其上方显示)的第一响应者?并且在使用上述解决方法时不会影响它?
【问题讨论】:
新打开的 popover 没有初始的 key 响应者,不能成为 key。您的代码手动强制第一响应者(关键事件)成为窗口。弹出窗口关闭屏幕后,您需要手动恢复第一响应者(因为您将其设置为 nil)。 嗯。好的。但是为什么拥有窗口会关心弹出框及其窗口内发生的事情呢?据我了解,响应者链是窗口本地的,一旦弹出窗口出现,它就是独立的。没有? 因为弹出窗口显示在隐藏窗口中,而底层窗口是它的父窗口。子窗口 - 不接受关键事件。不是 100% 确定这一切,但您可以使用 Hopper 分解 AppKit 以查看发生了什么。还要看看 recalculatekeyviewloop mikeabdullah.net/nspopover-key-view-loop.html 和 ***.com/questions/34612744/… 谢谢马雷克!肯定有一些提示。 【参考方案1】:弹出窗口是所属窗口的子窗口,并与其父窗口共享第一响应者。当弹出窗口关闭时,_NSPopoverCloseAndAnimate:
被调用。如果弹出框的第一响应者是NSView
的子类,则在所属窗口上调用_updateFirstResponderForIgnoredChildWindow:
并将设置第一响应者。如果弹出框的第一响应者是一个窗口,则所属窗口的第一响应者不会恢复。
如果弹出框不包含任何可以作为第一响应者的视图,则所属窗口的文本字段将保持第一响应者并接受按键。
【讨论】:
精彩的解释。谢谢!以上是关于NSWindow 在关闭 NSPopover 后失去了第一响应者的主要内容,如果未能解决你的问题,请参考以下文章