第一个响应者关于鼠标按下行为NSControl和NSView

问题描述 投票:0回答: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财产。它设置为false。

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

要覆盖的属性是needsPanelToBecomeKey

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

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

此属性也用于键盘导航。它确定鼠标单击是否应该为视图提供焦点 - 即,使其成为第一个响应者)。某些视图(例如,文本字段)希望在单击它们时接收键盘焦点。其他视图(例如,按钮)仅在您选中它们时才会获得焦点。您不希望焦点从简单因为您单击复选框的正在编辑的文本字段切换。

NSView返回trueNSControl返回false

© www.soinside.com 2019 - 2024. All rights reserved.