【发布时间】: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
-
谢谢马雷克!肯定有一些提示。
标签: swift appkit first-responder responder-chain