我有一个基于NSView的NStableView。在每一行中还有一个NSImageView,它是NSView的子视图。我把这个NSImageView子类化,然后重写了mouseDown方法。问题是当用户单击此imageview时,还会触发tableViewSelectionDidChange。我只希望调用mouseDown,而不希望tableViewSelectionDidChange。

如果将表的selectionHighlightStyle设置为NSTableViewSelectionHighlightStyle.None,则仅调用图像视图的mouseDown。如果我不将selectionHighlightStyle给予NSTableViewSelectionHighlightStyle.None,则将同时调用imageview的mouseDown和tableViewSelectionDidChange。将selectionHighlightStyle设置为none似乎可以解决我的问题,但这是正确的方法吗?还是由于appkit中的某些错误而导致出现这种情况?

我也找不到某个地方记录的这种行为。

最佳答案

我认为您是继承NSTableView并重写NSResponder方法-(BOOL)validateProposedFirstResponder:(NSResponder *)responder forEvent:(NSEvent *)event的正确方法

您将更好地控制哪个视图将获得鼠标事件,而不必像更改表格视图选择样式那样诉诸“黑客”。

从苹果文档:


  指定子视图应如何响应事件
  
  表中的视图或控件有时需要响应传入的事件。为了确定特定的子视图是否应该接收当前的鼠标事件,表视图在hitTest的实现中调用validateProposedFirstResponder:forEvent:。如果创建表视图子类,则可以重写validateProposedFirstResponder:forEvent:以指定哪些视图可以成为第一响应者。这样,您会收到鼠标事件。
  
  validateProposedFirstResponder:forEvent的默认NSTableView实现使用以下逻辑:
  
  对于所有建议的第一响应者视图,返回YES,除非它们是NSControl的实例或子类。
  确定建议的第一响应者是NSControl实例还是子类。
  
  如果控件是NSButton对象,则返回YES。
  
  如果该控件不是NSButton,则调用该控件的hitTestForEvent:inRect:ofView:来查看该点击区域是可跟踪的(即NSCellHitTrackableArea)还是可编辑的文本区域(即NSCellHitEditableTextArea),并返回适当的值。请注意,如果命中了文本区域,NSTableView也将延迟第一响应者操作。


https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/TableView/RowSelection/RowSelection.html#//apple_ref/doc/uid/10000026i-CH6-SW9

10-07 21:53