在 MacOS/Cocoa/Swift 4.2/Xcode 10.1 中,我试图创建一个浮动在我的文档窗口上的 NSPanel,作为与文档窗口中发生的(主要基于键盘的)编辑会话交互的轻量级标记调色板。
我在面板中主要有按钮控件,但是当用户单击它时,一个组合框值得关注。除此之外,我想避免成为关键窗口(避免捕获未来的关键事件并避免突出显示标题栏)当任何其他控件被按下时,或者当面板通过拖动重新定位时,或者面板点击时死角。这对我来说听起来与文档描述的行为完全一样,如果我的面板被标记为 becomeKeyOnlyIfNeeded,我应该有,但我无法让它工作。
在 Interface Builder 中,我将面板指定为(我自己的)子类 InspectorPanel,其样式为:常规面板、标题栏、阴影、关闭、可恢复和停用时隐藏设置(其他一切都清楚)。我在子类中指定了 becomeKeyOnlyIfNeeded:
class InspectorPanel : NSPanel {
override var becomesKeyOnlyIfNeeded: SwiftBool {
get {
return true
}
set {
}
}
}
(我也尝试将它设置在控制器的 awakeFromNib 中,在控制器的窗口中设置为?NSPanel。)
此设置似乎没有明显的效果。面板正确地漂浮在文档窗口上方,但是当组合框成功地从文档窗口中获取关键焦点时,按下任何控件、单击面板空白区域或拖动面板标题栏以及其他操作也是如此. 虽然我可以为每种情况编写处理程序,手动查找活动文档窗口并 makeKeyWindow(thatWindow) 将焦点传递回它所属的位置,但从检查器设计的角度来看,这似乎不优雅;强迫我写一些我目前不需要的处理程序(例如标题栏拖动);让我担心我错过的类似案例。
只有当我的单个组合框需要它时,是否有某种方法可以成功成为关键?如果是这样,怎么做?
其他努力:
我知道 needsPanelToBecomeKey 并且对其文档有些困惑。它表明,一旦我在面板上设置了 becomeKeyOnlyIfNeeded,NOTHING 将允许面板获取焦点,直到我在特定子视图(例如我的组合框)上启用 needsPanelToBecomeKey。实际上,由于设置 becomeKeyOnlyIfNeeded 对阻止窗口成为键没有任何影响,因此无论我是否在子视图上设置 comboBox.needsPanelToBecomeKey,我都看不出响应有什么不同。)
我也知道refusesFirstResponder,并尝试在面板中的各种控件(例如NSButtons)上设置它,看看这是否会阻止它们将关键焦点转移到窗口。没运气。)
如果我设置 canBecomeKeyWindow = false,那么即使在我的组合框中,我也不会获得关键焦点。(这似乎是合理且出乎意料的;我只是列出它是为了全面。)
许多其他应用程序似乎都有我想要的浮动窗口,但我没有找到可以帮助我找到错误的源代码。你能帮我吗?