1

我有一个自定义控件。如果它继承自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财产。它设置为假。

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

1 回答 1

4

要覆盖的属性是needsPanelToBecomeKey

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

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

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

NSView回报trueNSControl回报false

于 2019-03-09T17:32:51.697 回答