通过在界面生成器中设置自定义类,我对 NSOutlineView 的单元格进行了子类化。
我已经实现了这个委托(delegate)方法来配置单元格:
- (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item
此外,我已在自定义单元类中实现了此方法:
- (NSUInteger)hitTestForEvent:(NSEvent *)event inRect:(NSRect)cellFrame ofView:(NSView *)controlView
每次我单击单元格时都会调用两次。我想知道为什么不只一次。事件类型始终为 MouseDown。
我不知道这是否重要,但即使单元格没有 parent 或 child ,它也会被调用两次。所以它不可能是单元格层次结构。
如果我不能依靠 hitTestForEvent 在单击单元格的特定区域时触发操作,我应该使用哪种方法?
谢谢
最佳答案
-hitTestForEvent:inRect:ofView
完全是用来触发操作的错误方法。您应该使用 -trackMouse:inRect:ofView:untilMouseUp:
、或 -startTrackingAt:inView:
、-continueTracking:at: inView:
和 -stopTracking:at:inView:mouseIsUp:
。
重要提示:如果您在 -trackMouse:inRect:ofView:untilMouseUp:
中实现自己的鼠标跟踪循环,您应该在某处记录这一事实,因为一般来说它会排除其他三种方法的使用。 AppKit 框架中的一些 NSCell
子类会执行此操作,但无法记录它们已这样做(结果您将思考几个小时为什么会出现 -startTrackingAt:inView:
永远不会被调用)。
您如何实现自己的跟踪循环?像这样:
- (BOOL)trackMouse:(NSEvent *)theEvent inRect:(NSRect)cellFrame
ofView:(NSView *)controlView untilMouseUp:(BOOL)untilMouseUp
{
NSPoint pos = [controlView convertPoint:[theEvent locationInWindow]
fromView:nil];
if ([theEvent type] == NSLeftMouseDown && NSPointInRect (pos, myClickRect)) {
NSWindow *window = [controlView window];
NSEvent *myEvent;
NSDate *endDate = [NSDate distantFuture];
while ((myEvent = [window nextEventMatchingMask:(NSLeftMouseDragged
|NSLeftMouseUp)
untilDate:endDate
inMode:NSEventTrackingRunLoopMode
dequeue:YES])) {
if ([myEvent type] != NSLeftMouseUp)
continue;
pos = [controlView convertPoint:[theEvent locationInWindow]
fromView:nil];
if (NSPointInRect (pos, myClickRect)) {
// React somehow
}
return YES;
}
}
return [super trackMouse:theEvent inRect:cellFrame ofView:controlView
untilMouseUp:untilMouseUp];
}
(上面的代码只是在这里输入的,所以通常的注意事项适用;它假设存在一个名为 myClickRect
的 NSRect
,它定义了单元格的事件区域.您可能需要从方法开头的 cellFrame
计算该值。)
显然,如果其他事件与您相关,您也可以监视和处理它们。
也许我还应该补充一点,三方法方法虽然在概念上更清晰,但往往速度要慢一些,这通常导致我更喜欢覆盖 -trackMouse:inRect:ofView:untilMouseUp:
作为如上所示。
关于objective-c - hitTestForEvent :inRect:ofView is invoked twice in my NSOutlineView cells,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10649379/