基本的には、UIViewのサブクラスを自作してやり、その中のdrawRectメソッドで書き換え処理を行うこととなる。
作ったサブクラスは、Storyboardで画面全体に貼ってあるViewのCustom Classにくくりつけてやれば画面全体をドローキャンバスにできるし、StoryboardにUIViewを貼ってそれにくくりつけてやれば画面の一部だけをドローキャンバスにできる。
以下、RestOfTimeViewというUIViewのサブクラスにドロー画像を表示させる場合。
画面全体に貼ってあるViewにRestOfTimeViewをくくりつけてる。
サブクラス側には
- (void)drawRect:(CGRect)rect {}
メソッドのひな形がコメントアウトされた状態で書かれてるので、コメントを外して使う。
このメソッドがiOSが決めた画面更新のタイミングに従って呼ばれ、書き換えられるわけだ。
このメソッドを直接呼び出すことは禁止されてるので、プロパティを使って中の値にアクセスするとともに、呼出元のViewControllerから
setNeedsDisplayメソッドを使って画面更新を指示する。
RestOfTimeViewにrestOfTimeというプロパティがあった場合、そこにViewControllerからアクセスするには、RestOfTimeViewを#importした後に、以下のようにする。
ともに(RestOfTimeView *)を頭につけて()でくくり、自作カスタムクラスにキャスト(変換)してやらないとエラーになっちゃうことに注意。
キャストしないとself.viewもしくは_restOfTimeは、ただのUIViewクラスのままだからだそうだが、よくわからん。
その1:画面全体に貼ってあるUIViewにくくりついてる場合
((RestOfTimeView *)self.view).restOfTime = 30;
((RestOfTimeView *)(_restOfTime)).restOfTime = 30;
その1の場合
その2の場合
さて、実際のサブクラスの中身。
[self.view setNeedsDisplay];
[_restOfTime setNeedsDisplay];
Storyboardを使った場合と、コードでViewをalloc、initした場合とではイニシャライザが違う。
drawRectメソッドの中では、この例では
UIBezierPath *rectangle = [UIBezierPath bezierPathWithRect:self.bounds];
で四角形のパスを作り、
setStrokeで線の色を、setFillで塗りつぶしの色を、setLineWidthで線の太さをそれぞれ指定し、fill、strokeでそれぞれ線の描画、塗りつぶし描画をしてる。
他にも線をつなげた描いたり、円を描いたり、角の丸い四角を描いたり、ベジェ曲線を描いたりいろいろできる。
@implementation RestOfTimeView
//StoryboardからViewを読み込む場合
- (id)initWithCoder:(NSCoder *)aDecoder {
if ((self = [super initWithCoder:aDecoder])) {
self.backgroundColor = [UIColor yellowColor];
}
return self;
}
//コードでViewを作る場合
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
//initialization code
self.backgroundColor = [UIColor purpleColor];
}
return self;
}
- (void)drawRect:(CGRect)rect {
// Drawing code
//ベースの色
[[UIColor blueColor] setStroke];
[[UIColor redColor] setFill];
UIBezierPath *rectangle = [UIBezierPath bezierPathWithRect:self.bounds];
[rectangle setLineWidth:2];
[rectangle fill];
[rectangle stroke];
//残り時間
CGFloat restTimeWidth = self.bounds.size.width / 30 * _restOfTime;
CGRect restTimeRect = CGRectMake(self.bounds.origin.x, self.bounds.origin.y, restTimeWidth, self.bounds.size.height);
rectangle = [UIBezierPath bezierPathWithRect:restTimeRect];
[[UIColor blueColor] setFill];
[rectangle fill];
}
@end
重ね重ね、8ビットパソコンの頃よりめんどくさいんだけど、ガマンガマン。
0 件のコメント:
コメントを投稿