很难确切地知道最好的方法,因为我不知道你的应用程序做什么,但这里有一个想法。听起来您想通过视图层次结构向上传递消息……不知何故。
无论如何,视图会做以下两件事之一:
- 处理消息
- 将其传递给“下一个视图”(如何定义“下一个视图”取决于您的应用程序)
所以。你会怎么做?视图的默认行为应该是将消息传递给下一个视图。实现这种事情的一个好方法是通过一个非正式的协议。
@interface NSView (MessagePassing)
- (void)handleMouseDown:(NSEvent *)event;
- (NSView *)nextViewForEvent:(NSEvent *)event;
@end
@implementation NSView (MessagePassing)
- (void)handleMouseDown:(NSEvent *)event {
[[self nextView] handleMouseDown:event];
}
- (NSView *)nextViewForEvent:(NSEvent *)event {
// Implementation dependent, but here's a simple one:
return [self superview];
}
@end
现在,在应该具有该行为的视图中,您可以这样做:
- (void)mouseDown:(NSEvent *)event {
[self handleMouseDown:event];
}
- (void)handleMouseDown:(NSEvent *)event {
if (/* Do I not want to handle this event? */) {
// Let superclass decide what to do.
// If no superclass handles the event, it will be punted to the next view
[super handleMouseDown:event];
return;
}
// Handle the event
}
您可能希望创建一个NSView
子类来覆盖mouseDown:
您的其他自定义视图类。
如果您想根据实际 z 顺序确定“下一个视图”,请记住 z 顺序由subviews
集合中的顺序决定,后面的视图首先出现。所以,你可以这样做:
- (void)nextViewForEvent:(NSEvent *)event {
NSPoint pointInSuperview = [[self superview] convertPoint:[event locationInWindow] fromView:nil];
NSInteger locationInSubviews = [[[self superview] subviews] indexOfObject:self];
for (NSInteger index = locationInSubviews - 1; index >= 0; index--) {
NSView *subview = [[[self superview] subviews] objectAtIndex:index];
if (NSPointInRect(pointInSuperview, [subview frame]))
return subview;
}
return [self superview];
}
这可能比您想要的要多,但我希望它有所帮助。