ResponderChainとDelegate

UIKitでプログラミングしていると、サブビュー(UIViewとその派生)が次々と増えていく。


ビューが重なりあった状態では、最も下層にあるビューが、FirstResponderとなる。
FirstResponderというのは、最初にイベントを受け取るオブジェクトのこと。
例えば、TextFieldにフォーカスがあってたら、TextFieldがFirstResponderである。


で、指でViewに対してタッチすると、touches{Began|Moved|Ended}の一連のイベントが発生するが、
このイベントというのは、FirstResponderがまず受け取る。
FirstResponderにてイベントハンドラが定義されている場合、実行される。
イベントハンドラが定義されていなければ、NextResponderがFirstResponderになる。
UIViewの場合は、その親ビューにイベントが渡される。
このように、次々とスーパービューへとイベントが渡されていく。
これをResponderChainという。


FirstResponderにイベントハンドラがあるが、
その親ビューや、そのさらに親ビューのイベントハンドラや関数を実行したい場合は
Delegateを使う。


Delegateは大体の場合が、非公式プロトコルというObj-Cの仕組みで実装する。
Javaでいうところの、Interfaceのような感じ。


コンパイル通るかわからないけど、簡単な例を示すと、だいたい次のような感じ。
View1が、View2の親ビュー。
View2でタッチしたイベントを、View1にdelegateする。


というわけで、はてな様、私にMac11インチくださったら、役立てますので宜しくお願いします。

touchDelegate.h

@protocol touchDelegate
   - (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
@end

View1.m

#import "touchDelegate.h"
@interface View1:UIViewControler <touchDelegate>
{
   UILabel *label;
}
@end

@implementation View1
- (void) viewDidLoad
{
   UIView *view2 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100,100)];
   view2.delegate = self;
   [self.view addSubView:view2];
}
- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
   label.text = @"aho";
}
@end

View2.m

#import "touchDelegate.h"
@interface View2:UIViewController <touchDelegate>
{
   id delegate;
}
@end
@property (nonatomic,retain)id delegate;

@implementation View2
@synthesize delegate;
- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
   [delegate touchesBegan:touches withEvent:event];
}
@end