Трудно точно определить лучший подход, потому что я не знаю, что делает ваше приложение, но вот мысль. Похоже, вы хотите передать сообщения через иерархию представлений ... каким-то образом.
Независимо от того, представление сделало бы одну из двух вещей:
- обработать сообщение
- передать его в «следующее представление» (как вы определяете «следующее представление» зависит от вашего приложения)
Итак. Как бы вы это сделали? Поведение по умолчанию для представления должно состоять в том, чтобы передать сообщение следующему представлению. Хороший способ реализации подобных вещей - через неофициальный протокол.
@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];
}
Возможно, это намного больше, чем вы хотели, но я надеюсь, что это поможет.