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

First responder on mouse down behavior NSControl and NSView

我有一个自定义控件。如果继承自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。

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

要覆盖的 属性 是 needsPanelToBecomeKey

A Boolean value indicating whether the view needs its panel to become the key window before it can handle keyboard input and navigation.

The default value of this property is false. Subclasses can override this property and use their implementation to determine if the view requires its panel to become the key window so that it can handle keyboard input and navigation. Such a subclass should also override acceptsFirstResponder to return true.

This property is also used in keyboard navigation. It determines if a mouse click should give focus to a view—that is, make it the first responder). Some views (for example, text fields) want to receive the keyboard focus when you click in them. Other views (for example, buttons) receive focus only when you tab to them. You wouldn't want focus to shift from a textfield that has editing in progress simply because you clicked on a check box.

NSView returns true, NSControl returns false.