読者です 読者をやめる 読者になる 読者になる

delegate とは何か(5)

具体的に delegate を使うように記述します。

STtouchPointCircle は、丸の class です。

 

STtouchPointCircle.h

#import <UIKit/UIKit.h>

@class STtouchPointCircle; 

@protocol STTouchPointCircleDelegate

- (void) beginImageTouched:(NSSet *)touches withEvent:(UIEvent *)event;

- (void) duringTouchPoint:(NSSet *)touches withEvent:(UIEvent *)event;

- (void) endTouchPoint:(NSSet *)touches withEvent:(UIEvent *)event;

@end

@interface STtouchPointCircle : UIView

@property (weak) id delegate;

@end

はじめに、@class  でクラス名を規定します。この記述は必須ではありませんが、明示した方が後でわかりやすいので記述しています。

@protocol 部分は通知(delegate)の名前と、method 名を記述します。

ここで特徴的なのは、@protocol - @end  の間に宣言した method は、このクラスでは実装しない点です。

 

次に実装部分です。

STtouchPointCircle.m

- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event

{

    if ([self.delegate respondsToSelector:@selector(duringTouchPoint:withEvent:)])

    {

        [self.delegate duringTouchPoint:touches withEvent:event];

    }

}

 

丸をタッチしている最中、touchesMoved: メソッドが呼ばれます。

ここで、delegate を通じて header  で定義した method を呼び出しています。

丸のクラスでは header で method 名を宣言していて、実装部では呼び出しを行いますが、この method の具体的な記述は UIViewController.m で行います。

delegate の意味を辞書で調べると委託、委任などの意味であることがわかります。自身の class には宣言だけしておいて実装がなく、別の class に実装がなされることに由来した命名であることがわかります。

 

次に、UIViewController を見てみます。

UIViewController.h

#import <UIKit/UIKit.h>

#import "STControlPoint.h"

@interface ViewController : UIViewController<STTouchPointCircleDelegate>

@end

呼び出し元である STControlPoint.h を import します。

次に、@interface 部分で、<STTouchPointCircleDelegate> を記述し、この class が反応する protcol を記述します。この記述があることで、STTouchPointCircle が呼び出しを行うと、このクラスが反応することになります。

前に、delegate とは「赤ちゃんがオムツを替えてくれと泣くようなもの」と記載しましたが、とてもよく形容していると思います(ただ、赤ちゃんが泣くと皆が反応してしまい、人前だと親としては恐縮してしまうこともあるのですが、delegate の場合、protocol を通してあれば反応する、換言すると、protcol を通していないと反応しないという部分が違います。赤ちゃんが泣く例もそうだとよいのですが・・・)。

 

次に、実装部分を見てみます。

UIViewController.m

- (void) duringTouchPoint:touches withEvent:event

{

  CGPoint newLocation = [[touches anyObject] locationInView:self.canvas];  

  CGPoint oldLocation = [[touches anyObject] previousLocationInView:self.canvas];

  CGFloat deltaX = newLocation.x - oldLocation.x;

  CGFloat deltaY = newLocation.y - oldLocation.y;

  UITouch* touch = [touches anyObject];

  ...some codes...

}

 

STtouchPointCircle.h で宣言した method を、UIViewController.m で実装しています。

このように、delegate では宣言した class とは別の calss に実装します。