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