我有一个基于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