Objective-Cの継承を棒グラフアプリで理解しよう Part2.~drawRectで描く。具体的実装編~
前回:Objective-Cの継承を棒グラフアプリで理解しよう Part1.~継承を使おうと思うまでの考えと構造~
方針
具体的なクラス(たとえば、赤いグラフをつくろう、青いグラフをつくろう、みたいな)を想定し、その共通要素を考えてから抽象クラスをつくるというのが自然な流れになると思います。
今回の場合は複数の棒グラフ的なものをdrawRectで描きます。
赤いグラフ、青いグラフをつくってみて、
「あれ、ここの要素だけしか違わないんだったら、共通要素を取り出せる!」
みたいになるとよいです。
慣れてくるとはじめから高度に抽象的なクラスができる達人ももちろんいらっしゃると思いますが、
はじめは具体から抽象に考えていく、というのは変わらないと思います。
では、やっていきましょう。
赤い棒グラフ、青い棒グラフともにUIViewのサブクラスとして作成(初期段階)
「New File」の「Objective-C class」からUIViewを選択し、AgraphRedクラスを作成。
同じようにして、BgraphBlueクラスも作成。
すると、こんな感じになってますか?
drawRectで図形を描く
UIViewサブクラスでAgraphRedクラスとBgraphBlueクラスを作成しました。
最初の状態ではdrawRectメソッドはコメントアウトされていると思います。
なのでまずは複数行にわたっているコメントを消し、drawRectメソッドが使える状態にしてください。
コメント部分を消した状態は以下のようになります。
#import "AgraphRed.h" @implementation AgraphRed - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { // Initialization code } return self; } - (void)drawRect:(CGRect)rect { // Drawing code } @end
BgraphBlueクラスについても同様にしてください。
では、まずAgraphRedクラスについて実装します。
AgraphRed.m
#import "AgraphRed.h" @implementation AgraphRed - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { // Initialization code self.backgroundColor = UIColor.clearColor; //背景を透明に。背景のImageViewが見えるようにするため } return self; } - (void)drawRect:(CGRect)rect { // Drawing code CGContextRef context = UIGraphicsGetCurrentContext(); // コンテキストを取得 // グラフの色 CGContextSetStrokeColorWithColor(context,UIColor.redColor.CGColor); //赤色 // 線の太さを指定 CGContextSetLineWidth(context, 10.0); // 10ptに設定 CGContextMoveToPoint(context, 50, 110); // 始点、110は高さ CGContextAddLineToPoint(context, 200, 110); // 終点 CGContextStrokePath(context); // 描画 }
今回のテーマは「継承」で「drawRect」の解説ではないので、drawRectについては別をご参照ください。
BgraphBlueクラスを実装します。
BgraphBlue.m
#import "BgraphBlue.h" @implementation BgraphBlue - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { // Initialization code self.backgroundColor = UIColor.clearColor; //背景を透明に。背景のImageViewが見えるようにするため } return self; } - (void)drawRect:(CGRect)rect { // Drawing code CGContextRef context = UIGraphicsGetCurrentContext(); // コンテキストを取得 // グラフの色 CGContextSetStrokeColorWithColor(context,UIColor.blueColor.CGColor); //青色 // 線の太さを指定 CGContextSetLineWidth(context, 10.0); // 10ptに設定 CGContextMoveToPoint(context, 50, 160); // 始点、160は高さ CGContextAddLineToPoint(context, 100, 160); // 終点 CGContextStrokePath(context); // 描画 } @end
ViewControllerにaddSubviewしてUIViewをのっける
AgraphRedとBgraphBlueクラスのインスタンスをつくり、サイズはinitWithFrameでself.view.boundsを指定。
ViewController.m
#import "ViewController.h" #import "AgraphRed.h" #import "BgraphBlue.h" @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; AgraphRed *ag = [[AgraphRed alloc] initWithFrame:self.view.bounds]; [self.view addSubview:ag]; BgraphBlue *bg = [[BgraphBlue alloc] initWithFrame:self.view.bounds]; [self.view addSubview:bg]; } - (void)viewDidUnload { [super viewDidUnload]; // Release any retained subviews of the main view. } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); } @end
そして、ViewController.xibにUIImageViewをはりつけて背景としておいてください。
実行してみると、できているはずです。
次回はこれを発展させて、抽象クラスをつくってみます!