NSTableView,使它对用户友好

NSTableView, making it user-friendly

我有一个基于 NSTableView 视图的具有可编辑行的视图,但如果用户单击文本而不是单元格的其余部分,则只允许编辑。 (见图)

有人知道如何让整个单元格都可编辑,而不仅仅是显示文本的单元格区域吗?

我相信我明白发生了什么。

首先,您能否确认在实际编辑文本字段时,焦点环包含整个 table 单元格?它不仅仅是围绕实际的当前文本,对吧?

如果它包含整个 table 单元格,则确认约束正在拉伸它以填充 table 单元格而不是包含其内容的文本字段。换句话说,我试图确认图像中的 "Not Editable" 箭头确实指向文本字段的一部分。我希望如此。

所以,除了这个,问题是 NSTableView 如何管理点击以及他们是否将点击的视图设置为第一响应者。从 Table View Programming Guide for Mac: Enabling Row Selection and User Actions – Specifying How Subviews Should Respond to Events,我们了解到 table 视图在 validateProposedFirstResponder(_:forEvent:):

的重写中实现了特殊逻辑

The default NSTableView implementation of validateProposedFirstResponder:forEvent: uses the following logic:

  1. Return YES for all proposed first responder views unless they are instances or subclasses of NSControl.

  2. Determine whether the proposed first responder is an NSControl instance or subclass.

    • If the control is an NSButton object, return YES.

    • If the control is not an NSButton, call the control’s hitTestForEvent:inRect:ofView: to see whether the hit area is trackable (that is, NSCellHitTrackableArea) or is an editable text area (that is, NSCellHitEditableTextArea), and return the appropriate value. Note that if a text area is hit, NSTableView also delays the first responder action.

我已经实现了 NSTextFieldCell 的自定义子 class。它所做的唯一一件事就是覆盖 hitTestForEvent(_:inRect:ofView:) 以调用 super,记录结果,然后 return 它。然后,我在 table 单元格视图中设置文本字段,以将自定义 class 用于其单元格。从那里,我了解到单击文本字段的空白区域会导致 .None。单击实际文本会导致 .ContentArea | .EditableTextArea

第一个结果不会导致 NSTableView 实施 validateProposedFirstResponder(_:forEvent:) 以允许提议的第一响应者实际成为第一响应者。后一个结果确实如此。

因此,您可以实现自己的 NSTextFieldCell 的子 class,它会覆盖 hitTestForEvent(_:inRect:ofView:)。在你的覆盖中,你会打电话给超级。如果结果是 .None,您可以在 return 之前将其更改为 .ContentArea | .EditableTextArea。然后,将自定义单元格 class 用于 table.

中的文本字段

或者,您可以尝试使用覆盖 validateProposedFirstResponder(_:forEvent:)NSTableView 的自定义子 class 来解决此问题。问题是重新实现该方法的逻辑并不简单,除了它响应的命中测试代码。