連載
» 2010年12月15日 00時00分 公開

SDKで始めるiPad/iPhoneアプリ開発の勘所(5):Core Graphicsで作るiPad向けお絵描きアプリの基礎 (2/4)

[竹内彰吾,株式会社ビーブレイクシステムズ]

Core Graphicsフレームワークで“タッチ”を描画に

 iPhone/iPadアプリでは、文字や画像・アニメーションなど、画面表示を操作するフレームワークがいくつか用意されています。今回のように指でタッチした部分に線を描いていくといった場合は、主に以下の2通りの実装方法が考えられます。

  1. グラフィック描画に適した「Core Graphics」フレームワークを用いる。内部的には「Quartz(クオーツ)」と呼ばれる描画エンジンを使用している
  2. 組み込みシステムで広く使用されている3D描画用API「OpenGL ES)」を用いる
OpenGL ES(OpenGL for Embedded Systems)
携帯情報端末や組み込み向けのOpenGLのサブセット。OpenGLは、一般的に普及しているグラフィックスプログラミング用のC/C++のAPIのこと

 OpenGLは3Dに特化し、ゲームアプリなどでよく使用されています。今回は線を描画するのみということと、よりCocoaTouchと親和性の高いということで、Core Graphicsフレームワークを用いて解説します。

キャンバスの用意

 テンプレートから作成された「Detail view content goes here」と書かれているViewの上を、実際に指でなぞって絵を描くキャンバスの部分にしていきます。この文字列が書かれたLabelは必要がないので削除しましょう。

 Xcodeの[グループとファイル]→[Resources]→[DetailView.xib]をクリックし、InterfaceBuilderからLabelの行を選択後、[delete]ボタンで削除し、保存します。

 Xcodeの[グループとファイル]→[Classes]から、キャンバス部分を担当するDetailViewControllerを選択し、実際の描画対象となる「UIImageViewクラスのインスタンスをViewの上に配置します。

@interface DetailViewController : UIViewController <UIPopoverControllerDelegate,UISplitViewControllerDelegate> {
    UIPopoverController *popoverController;
    UIToolbar *toolbar;
 
    id detailItem;
    UILabel *detailDescriptionLabel;
 
    // 以下を追加
    UIImageView *canvas;
    CGPoint touchPoint;
}
DetailViewController.h
- (void)viewDidLoad {
    [super viewDidLoad];
    
    // キャンバスのインスタンスを生成
    canvas = [[UIImageView alloc] initWithImage:nil];
    canvas.backgroundColor= [UIColor whiteColor];
    canvas.frame = self.view.frame;
    [self.view insertSubview:canvas atIndex:0];
}
DetailViewController.m

 キャンバス部分となるcanvasと、指でタッチした画面のxy座標を保持するtouchPointを作成しました。次は、このcanvasに線を描画していきましょう。

 注意点として、deallocメソッドによるインスタンスの解放は忘れずにしておきましょう!

タッチイベントの取得

 次に「指で画面をタッチした場合」のタッチイベントを取得するメソッドを、先ほど作成したcanvasを保持するDetailViewControllerに記述します。

// 画面に指をタッチしたとき
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
}
 
// 画面に指がタッチされた状態で動かしているとき
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
}
DetailViewController.m

 どちらのメソッドもUIResponderクラスに定義されており、DetailViewControllerはこのクラスを継承して作成されているため、上記メソッドをそのまま記述することでタッチイベントを取得できます。

線の描画

 メソッドの中身を実装していきます。

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
 
    // タッチ開始座標をインスタンス変数touchPointに保持
    UITouch *touch = [touches anyObject];
    touchPoint = [touch locationInView:canvas];
}
 
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
 
    // 現在のタッチ座標をローカル変数currentPointに保持
    UITouch *touch = [touches anyObject]; 
    CGPoint currentPoint = [touch locationInView:canvas];
    
    // 描画領域をcanvasの大きさで生成
    UIGraphicsBeginImageContext(canvas.frame.size);
    
    // canvasにセットされている画像(UIImage)を描画
    [canvas.image drawInRect:
        CGRectMake(0, 0, canvas.frame.size.width, canvas.frame.size.height)];
    
    // 線の角を丸くする
    CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
    
    // 線の太さを指定
    CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 10.0);
    
    // 線の色を指定(RGB)
    CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 0.0, 0.0, 0.0, 1.0);
    
    // 線の描画開始座標をセット
    CGContextMoveToPoint(UIGraphicsGetCurrentContext(), touchPoint.x, touchPoint.y);
    
    // 線の描画終了座標をセット
    CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
    
    // 描画の開始〜終了座標まで線を引く
    CGContextStrokePath(UIGraphicsGetCurrentContext());
    
    // 描画領域を画像(UIImage)としてcanvasにセット
    canvas.image = UIGraphicsGetImageFromCurrentImageContext();
    
    // 描画領域のクリア
    UIGraphicsEndImageContext();
    
    // 現在のタッチ座標を次の開始座標にセット
    touchPoint = currentPoint;
}
DetailViewController.m

 touchesBeganメソッドで最初のタッチ座標を記憶し、touchesMovedメソッドで指を動かした座標まで線を描画する処理を行っています。touchesMovedメソッドは指を画面にタッチしている間は、ループのように常に実行されます。

 touchesMovedの中身を見ていくと、「CGContext〜」という関数に値を渡して描画処理を行っています。これがCore Graphicsフレームワークが提供する関数であり、「UIGraphics〜」関数で作成された描画領域に、座標や形状、「どこからどこまで線を引くか」といった指示を与えることで描画が行われるようになっています。

 このような描き方がCore Graphicsフレームワークを用いた実装の特徴であり、描画方法に応じたさまざまな関数がほかにも用意されています。

 それでは、iPhoneシュミレータを起動して動作を確認してみましょう。

 無事に絵を描けたでしょうか。次ページでは、指で描いた線に色を付けられるようにします。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。