あなたのアプリケーションが何をするかわからないので、最適なアプローチを正確に知ることは困難ですが、ここに考えがあります。ビュー階層を介してメッセージを渡したいようです...どういうわけか。
とにかく、ビューは次の 2 つのいずれかを行います。
- メッセージを処理する
- それを「次のビュー」に渡します(「次のビュー」を定義する方法はアプリケーションによって異なります)
そう。これをどのように行いますか?ビューのデフォルトの動作は、メッセージを次のビューに渡すことです。この種のことを実装する良い方法は、非公式のプロトコルを使用することです。
@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];
}
これはあなたが望んでいたよりもはるかに多いかもしれませんが、それが役に立てば幸いです.