1

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

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

表视图

细胞

4

1 回答 1

1

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

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

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

因此,除此之外,问题在于如何NSTableView管理点击以及他们是否将点击的视图设置为第一响应者。从Mac 的表视图编程指南:启用行选择和用户操作 - 指定子视图应如何响应事件中,我们了解到表视图在覆盖中实现了特殊逻辑validateProposedFirstResponder(_:forEvent:)

的默认NSTableView实现 validateProposedFirstResponder:forEvent:使用以下逻辑:

  1. 返回YES所有建议的第一响应者视图,除非它们是NSControl.

  2. 确定提议的第一响应者是NSControl实例还是子类。

    • 如果控件是NSButton对象,则返回YES

    • 如果控件不是NSButton,则调用控件hitTestForEvent:inRect:ofView:以查看命中区域是可跟踪的(即NSCellHitTrackableArea)还是可编辑的文本区域(即NSCellHitEditableTextArea),并返回适当的值。请注意,如果文本区域被击中,NSTableView也会延迟第一响应者的操作。

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

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

因此,您可以实现自己的NSTextFieldCell覆盖子类hitTestForEvent(_:inRect:ofView:)。在你的覆盖中,你会打电话给超级。如果结果是.None,则.ContentArea | .EditableTextArea在返回之前将其更改为 。然后,为表格中的文本字段使用该自定义单元格类。

或者,您可以尝试通过使用NSTableViewoverrides的自定义子类来解决这个问题validateProposedFirstResponder(_:forEvent:)。问题在于,除了它响应哪些命中测试代码之外,重新实现该方法的逻辑并不简单。

于 2016-03-20T23:52:56.937 回答