1

在 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) 将焦点传递回它所属的位置,但从检查器设计的角度来看,这似乎不优雅;强迫我写一些我目前不需要的处理程序(例如标题栏拖动);让我担心我错过的类似案例。

只有当我的单个组合框需要它时,是否有某种方法可以成功成为关键?如果是这样,怎么做?

其他努力:

  1. 我知道 needsPanelToBecomeKey 并且对其文档有些困惑。它表明,一旦我在面板上设置了 becomeKeyOnlyIfNeeded,NOTHING 将允许面板获取焦点,直到我在特定子视图(例如我的组合框)上启用 needsPanelToBecomeKey。实际上,由于设置 becomeKeyOnlyIfNeeded 对阻止窗口成为键没有任何影响,因此无论我是否在子视图上设置 comboBox.needsPanelToBecomeKey,我都看不出响应有什么不同。)

  2. 我也知道refusesFirstResponder,并尝试在面板中的各种控件(例如NSButtons)上设置它,看看这是否会阻止它们将关键焦点转移到窗口。没运气。)

  3. 如果我设置 canBecomeKeyWindow = false,那么即使在我的组合框中,我也不会获得关键焦点。(这似乎是合理且出乎意料的;我只是列出它是为了全面。)

许多其他应用程序似乎都有我想要的浮动窗口,但我没有找到可以帮助我找到错误的源代码。你能帮我吗?

4

2 回答 2

1

我发现了我的问题的原因。显然我不明白我用来覆盖上面 becomeKeyOnlyIfNeeded 的 Swift 初始化程序的含义(尽管我在其他地方成功地对其他属性使用了相同的语法!)。如果我删除了将 becomeKeyOnlyIfNeeded 定义为始终为true 的尝试,而是沿着窗口初始化的路径将其(继承的属性)动态设置为 true,则面板的行为完全符合我的意愿,除了“如果需要”之外,其他的键焦点会被拒绝(在组合框中单击时)。

换句话说,

class InspectorPanel : NSPanel {

  override func awakeFromNib() {
    super.awakeFromNib()
    becomesKeyOnlyIfNeeded = true // REPLACES THE BELOW
  }

  /* REPLACED BY ABOVE
  override var becomesKeyOnlyIfNeeded: SwiftBool {
    get {
        return true
    }
    set {

    }
  }
  */
}

完美运行。如果有人理解我的(注释掉的)初始化程序做错了什么,我会很感激你的洞察力,但通过这个解决方法,我可以关闭关于面板行为的未决问题。

于 2019-03-05T20:53:36.530 回答
0

NSWindowStyleMaskUtilityWindow在以编程方式创建NSPanel(的子类)时使用样式掩码NSWindow,或者在 IB 中指定“实用程序面板”样式。

这种风格定义了浮动调色板窗口的外观和行为。

于 2019-03-04T20:47:33.240 回答