首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >MacOS:如何让NSPanel拒绝关键焦点(使用becomesKeyOnlyIfNeeded?)

MacOS:如何让NSPanel拒绝关键焦点(使用becomesKeyOnlyIfNeeded?)
EN

Stack Overflow用户
提问于 2019-03-05 03:19:48
回答 2查看 457关注 0票数 1

在MacOS/Cocoa/swift4.2/xcode10.1中,我试图创建一个NSPanel,它作为一个轻量级的标记调色板浮动在我的文档窗口上,它与文档窗口中发生的(主要是基于键盘的)编辑会话进行交互。

我在面板中有大多数按钮控件,但有一个组合框,当用户在其中单击时,它值得关注。除此之外,我希望避免在按下任何其他控件时,或者在面板通过拖动重新定位时,或者在面板单击死区时,成为按键窗口(避免捕获未来的按键事件和避免突出显示标题栏)。在我看来,这与文档描述的如果我的面板被标记为becomeKeyOnlyIfNeeded时应该具有的行为一模一样,但我无法让它正常工作。

在界面生成器中,我将面板指定为(我自己的)子类InspectorPanel,其样式为:常规面板、标题栏、阴影、关闭、可恢复和停用时隐藏设置(其他所有设置均已清除)。我在子类中指定了becomesKeyOnlyIfNeeded:

代码语言:javascript
复制
class InspectorPanel : NSPanel {
     override var becomesKeyOnlyIfNeeded: SwiftBool {
        get {
            return true
        }
        set {
        }
    }    
}

(我也尝试过在控制器的awakeFromNib中,在控制器的窗口中将其设置为?NSPanel。)

此设置似乎没有明显的效果。面板正确地浮动在文档窗口上方,但是当组合框成功地将键焦点从文档窗口上移开时,按下任何控件、在面板空白区域中单击、拖动面板标题栏,以及其他可能的操作也是如此。虽然我可以为每种情况编写处理程序,手动查找活动文档窗口和makeKeyWindow(thatWindow)以将焦点传递回它所属的位置,但从检查器设计的角度来看,这似乎并不优雅;迫使我编写一些我目前不需要的处理程序(例如标题栏拖动);这让我担心我遗漏了类似的情况。

有没有什么方法可以只在我的单个组合框需要时才能成功地成为key?如果是这样的话,是怎么做的?

其他努力:

  1. 我知道needsPanelToBecomeKey,但对它的文档有些困惑。它表明,一旦我在面板上设置了becomesKeyOnlyIfNeeded,在我对特定的子视图(例如,我的组合框)启用needsPanelToBecomeKey之前,任何东西都不允许面板获得焦点。事实上,由于设置becomesKeyOnlyIfNeeded对阻止窗口成为关键字没有任何影响,因此我看不出是否在子视图上设置comboBox.needsPanelToBecomeKey的响应有什么不同。)
  2. 我也知道refusesFirstResponder,并尝试在面板中的各种控件(例如NSButtons)上设置它,看看这是否会阻止它们将关键焦点转移到窗口。
  3. 如果我设置了canBecomeKeyWindow = false,那么我就永远得不到关键焦点,即使在我的comboBox中也是如此。(这似乎是合理且出乎意料的;我只是将其列为comprehensive.)

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-03-06 04:53:37

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

换句话说,

代码语言:javascript
复制
class InspectorPanel : NSPanel {

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

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

    }
  }
  */
}

效果很好。如果任何人理解我的(注释掉的)初始化器做错了什么,我将非常感谢你的洞察力,但通过这个变通方法,我可以结束关于面板行为的公开问题。

票数 1
EN

Stack Overflow用户

发布于 2019-03-05 04:47:33

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

此样式定义浮动调色板窗口的外观和行为。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54990155

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档