鼠标按下行为 NSControl 和 NSView 的第一响应者

Posted

技术标签:

【中文标题】鼠标按下行为 NSControl 和 NSView 的第一响应者【英文标题】:First responder on mouse down behavior NSControl and NSView 【发布时间】:2019-03-09 14:15:45 【问题描述】:

我有一个自定义控件。如果它继承自NSView,当我点击它时它会自动成为第一响应者。如果它继承自 NSControl,则不会。这种行为差异仍然存在,即使我覆盖 mouseDown(with:) 并且不调用 super。

代码:

class MyControl: NSView 
  override var canBecomeKeyView: Bool       return true 
  override var acceptsFirstResponder: Bool  return true 
  override func drawFocusRingMask()         bounds.fill() 
  override var focusRingMaskBounds: NSRect  return bounds 

  override func draw(_ dirtyRect: NSRect) 
    NSColor.white.set()
    bounds.fill()
  

如您所见,我在其他与键视图和响应程序相关的方法和属性中覆盖了acceptsFirstResponder。我还检查了refusesFirstResponder 属性。它设置为 false。

    造成这种行为差异的原因是什么? 是否有我可以重写以影响它的方法或属性? 假设我希望视图在单击时成为第一响应者并且视图继承自 NSControl 的行为,在我的鼠标按下事件处理程序的开头调用 window!.makeFirstResponder(self) 是一个很好的解决方案,或者有更好的解决方案?

【问题讨论】:

NSControl的文档,搜索“firstresponder”,你会找到refusesFirstResponder。也许这是覆盖的方法。 我知道那个属性。默认设置为false 【参考方案1】:

要覆盖的属性是needsPanelToBecomeKey

一个布尔值,指示视图是否需要其面板成为关键窗口才能处理键盘输入和导航。

此属性的默认值为 false。子类可以覆盖此属性并使用它们的实现来确定视图是否需要其面板成为关键窗口,以便它可以处理键盘输入和导航。这样的子类也应该重写 AcceptFirstResponder 以返回 true。

此属性也用于键盘导航。它确定鼠标单击是否应将焦点放在视图上——也就是说,使其成为第一响应者)。某些视图(例如,文本字段)希望在您单击它们时获得键盘焦点。其他视图(例如,按钮)仅在您选择它们​​时才会获得焦点。您不希望仅仅因为单击复选框而将焦点从正在进行编辑的文本字段转移。

NSView 返回trueNSControl 返回false

【讨论】:

以上是关于鼠标按下行为 NSControl 和 NSView 的第一响应者的主要内容,如果未能解决你的问题,请参考以下文章

NSControl 和 NSCell:以正确的方式管理单元状态

macOS 开发-NSView

当要求 NSView 辞去第一响应者的职务时,如何获得 firstResponder-to-be?

UIView.subviews 和 [NSView subviews] 之间的行为差​​异

NSView 子视图和类型

Swift:在Container View / NSView中切换NSViewController