iPhone/iPadスマートアプリ開発レシピ
iPhone/iPadスマートアプリ開発レシピ(5)

iOSでマルチタッチができるアプリを作るための初歩


クラスメソッド株式会社
開発部 平井祐樹
2012/8/7

「UIResponder」のメソッドを実際に使ってみよう

 「Single View Application」テンプレートを使用して新しいXcodeプロジェクトを作成し、以下のコードを「ViewController.m」に貼り付けて実行してみましょう。

// 画面に指を一本以上タッチしたときに実行されるメソッド
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"touches count : %d (touchesBegan:withEvent:)", [touches count]);
}
 
// 画面に触れている指が一本以上移動したときに実行されるメソッド
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"touches count : %d (touchesMoved:withEvent:)", [touches count]);
}
 
// 指を一本以上画面から離したときに実行されるメソッド
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"touches count : %d (touchesEnded:withEvent:)", [touches count]);
}
 
// システムイベントがタッチイベントをキャンセルしたときに実行されるメソッド
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"touches count : %d (touchesCancelled:withEvent:)", [touches count]);
}
- PR -

 上記コードを実行して画面を触ってみてください。すると、それぞれのタイミングでログが出力されるはずです。しかし、このままだと複数の指でタッチしても、touches countは「1」のままとなってしまいます。

UIViewのmultipleTouchEnabledプロパティ

 実は、マルチタッチを検出するためにはUIViewクラスのプロパティであるmultipleTouchEnabledをYESに設定しなければなりません。

 それでは、「ViewController.m」に定義されている- viewDidLoadメソッドに以下のソースコードを追加して実行してみましょう。

- (void)viewDidLoad
{
    // マルチタッチイベントを検出する
    self.view.multipleTouchEnabled = YES;
}

 画面を複数の指でタッチすると、ログにタッチした指の数が表示されるはずです。

引数touches = 画面上すべての指ではない!

 今度は、UIViewController.mに記述したtouchesBegan:withEvent:メソッド以外を削除してから再度実行し、画面を3本の指で同時にタップしてみてください。ログに「3」と表示されればいいのですが、どうでしょうか。

 結果は、タイミングよく3本の指でタップすればうまくいくが、少しでもずれるとうまくいかないはずです。

 それもそのはず、実はログの表示に使用しているイベントメソッドの引数touchesは、あくまでイベント発生に関連したUITouchだけしか通知してくれないのです。言い換えると、引数touchesは画面をタッチしているすべての指を表すものではないということです。

UIEventオブジェクト

 そこで、UIEventオブジェクトの登場です。UIEventオブジェクトは複数の指でタッチしている間存続します。そして、allTouchesメソッドより、マルチタッチ中のすべての指のUITouchオブジェクトを取得できます。これにより、それぞれのイベントメソッド内で、画面にタッチしているすべての指を検出できるわけです。

 さて、今度はViewController.mに記述したtouchesBegan:withEvent:メソッドの中身を以下のように変更して実行してみましょう。

// 画面に指を一本以上タッチしたときに実行されるメソッド
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"allTouches count : %d (touchesBegan:withEvent:)", [[event allTouches] count]);
}

 いかがでしょうか。画面に触れている指の本数がログにうまく表示されるはずです。

iOSで検出できる指の本数は5本まで

 iOSで検出できる指の本数は最大で5本までとなっています(2012年7月16日現在)。それでは、5本以上の指でタッチするとどうなるのでしょうか。結論から言うと、touchesCancelled:withEvent:メソッドが呼び出され、すべてのUITouchがキャンセルされてしまいます。

 以下のコードをViewController.mに記述して確認してみましょう。

// システムイベントがタッチイベントをキャンセルしたときに実行されるメソッド
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"allTouches count : %d (touchesCancelled:withEvent:)", [[event allTouches] count]);
}

 いかがでしょうか。6本以上の指で画面をタッチすると、touchesCancelled:withEvent:メソッドが呼び出されることが確認できるはずです。

反射神経測定iPhoneアプリを作ろう

 それでは、今までの内容を踏まえて、マルチタッチイベントを使用した反射神経測定アプリを作成してみましょう。アプリの仕様は以下の通りです。

  • スタートボタンでゲーム開始
  • ゲームが開始すると、適当なタイミングで四角形が表示
  • 表示される四角形は9×9マスの適当な場所に1〜5個までランダムに表示
  • 表示された四角形をすべて同時にタップできればゲームクリア
  • 四角形が表示されてからゲームクリアまでの経過時間を測定し表示
図2 アプリを実行したときの様子

 ここからは、サンプルアプリのソースコードの主要な部分を見ていきたいと思います。完成したアプリのソースコードは、こちらからダウンロードしてください

マルチタッチイベントの有効化

 UIViewクラスのプロパティであるmultipleTouchEnabledはInterface Builderからも設定できます。

図3 Interface BuilderからMultiple Touchを設定

マルチタッチイベント発生時の処理

 今回はゲームの都合上、座標を簡単に計算できるようにするため、UIViewControllerではなくUIViewを継承したTouchViewクラスを作成してマルチタッチイベントを処理するようにしました。

// 画面がタッチされた瞬間に実行されるメソッド
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    // 判定メソッドを実行する
    [self judgement:[event allTouches]];
}
 
// 画面にタッチしている指を動かしているときに実行されるメソッド
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    // 指を動かしている間も判定メソッドを実行する
    [self judgement:[event allTouches]];
}
 
// 画面から指が離れた瞬間に実行されるメソッド
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    // 何もしない
}
 
// タッチイベントがキャンセルされたときに実行されるメソッド
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    // 何もしない
}

 やっていることは非常に簡単で、touchesBegan:withEvent:メソッド、touchesMoved:withEvent:メソッド内でゲームをクリアしているかどうか判定するメソッドに対して、UIEventオブジェクトのallTouchesで得たセットオブジェクトを渡してあげるだけです。

ゲームクリア判定処理

 上記のタッチイベントメソッドで渡されたセットオブジェクトに格納されているUITouchオブジェクトの座標を1つずつ確認し、四角形がタッチされたか判定します。

 なお、UITouchオブジェクトの座標は、locationInView:メソッドより基点となるビューオブジェクト指定して求められます。

- (void)judgement:(NSSet *)allTouches
{
    // _pointsに何もセットされていなければ、まだゲームを開始していないとみなし、何もしない
    if (_points == nil)
    {
        return;
    }
    
    // 配置した矩形の座標コレクションを複製
    NSMutableSet *answers = [NSMutableSet setWithSet:_points];
    
    // タッチ中に指の数だけループ
    for (UITouch *touch in allTouches)
    {
        // タッチイベントの座標を取得する
        CGPoint touchPoint = [touch locationInView:self];
        NSInteger x = floor(touchPoint.x / RECT_WIDTH);
        NSInteger y = floor(touchPoint.y / RECT_HEIHT);
        
        // ゲームで使用する値に変換
        NSDictionary *point = [self makePointWithX:x andY:y];
        
        // タッチした座標が、ゲーム開始時に配置した矩形の座標コレクションに含まれていたら、
        // その座標を複製したコレクションから削除する
        if ([answers containsObject:point] == YES)
        {
            [answers removeObject:point];
        }
    }
    
    // 複製したコレクションが0個なら、すべてタッチできた(ゲームクリア)と見なす
    if ([answers count] == 0)
    {
        _points  = nil;
        
        // 矩形をすべて削除する
        for (UIView *view in [self subviews])
        {
            [view removeFromSuperview];
        }

        // ViewControllerにゲーム終了処理をデリゲートする
        [self.delegate finish];
    }
}

マルチタッチイベントを制する者はiOSアプリ開発を制す

 前回までの記事の内容と比べると大変地味な内容ですが、当たり前であるが故に、うろ覚えの方も多いかと思います。いざやってみると、間違った解釈をしていたりするので注意が必要です(実際に私がそうでした)。

 「マルチタッチイベントを制するものはiOSアプリ開発を制する……」とまでは言い切れませんが、ぜひ皆さんもいろいろ試してみてください。

■ @IT関連記事


iPhoneアプリ開発入門
盛り上がるiOS(iPhone・iPad・iPod touch)アプリ開発。そのハウツーや魅力に関する@IT記事一覧です

Core Graphicsで作るiPad向けお絵描きアプリの基礎
SDKで始めるiPad/iPhoneアプリ開発の勘所(5) 画面を指でなぞって絵を描くiPad用アプリ作成の基本や、Core Graphicsフレームワークの便利なAPIを解説します
Smart & Social」フォーラム 2010/12/15
画像をタッチ編集! アートなiPhoneカメラアプリを作る
Retinaに映える! iOS美麗アプリ制作入門(3) カメラの起動やピクセル情報の扱いが簡単なopenFrameworksを使ってタッチやドラッグで画像の色見を変えるアプリを作ろう
Smart & Social」フォーラム 2012/5/8
iPhoneをリモコンにしてみる
次世代のインプットを考えよう(1) マウスやキーボードだけではつまらない。Flashを応用して、iPhoneやバランスWiiボード、Chumbyを入力デバイスにしてみよう
Smart & Social」フォーラム 2009/1/9
Android 3.0の新APIで簡単ドラッグ&ドロップ実装
Androidで動く携帯Javaアプリ作成入門(23) 
3.0対応端末とSDKのリリースで本格的に到来した「Androidタブレット」時代。ユーザーに快適な操作を提供する実装方法を解説
Smart & Social」フォーラム 2011/3/8
第272話 タッチインターフェイス
4コマまんが「がんばれ!アドミンくん」
 スマホにタブレット、いまや家庭で電車で会社でみんなスリスリ。いいぁな、わしもスリスリしてみたい…。おっこんなところに!
Windows Server Insider」フォーラム 2011/6/21
第313話 誤タッチ
4コマまんが「がんばれ!アドミンくん」
 スマホの着信履歴にうっかり誤タッチして、その気もないのに取引先の部長に電話かけちゃったよ…。いやぁ、あせったあせった
Windows Server Insider」フォーラム 2012/4/24
Windows PhoneのMetro UIをタッチでジェスチャ操作
Silverlightベースで作るWP7アプリ開発入門(4)
 Windows 8の発表で話題のタッチ操作のMetro。Windows Phoneでも共通するマルチタッチのジェスチャについて解説
Smart & Social」フォーラム 2011/10/3
マルチタッチのWindows 7アプリ作成の基礎
楽しいWindows 7アプリ作成入門(1) 
画面を触って字や絵を描いたり、アプリを操作するには何をどうすればいいのだろう? 具体的なコードやデモとともに一から教えます
Windowsでもスマートにできるマルチタッチの基礎知識
Windowsタブレット向けマルチタッチアプリ開発(1) 
iPhoneの登場で一般的になったマルチタッチ。Windows 7での対応状況やタッチ操作をシミュレートできるアプリを紹介
Smart & Social」フォーラム 2011/6/24
Metro UIの肝となる「マルチタッチ」アプリの作り方
Windowsタブレット向けマルチタッチアプリ開発(2) 
Windows PhoneやWindows 8を含め、タッチUI全般の5つのポイントや具体的なタッチアプリ開発方法について解説
Smart & Social」フォーラム 2011/10/20

1-2  

 INDEX
iPhone/iPadスマートアプリ開発レシピ(5) 
iOSでマルチタッチができるアプリを作るための初歩
  Page1
簡単そうで難しいマルチタッチのイベント処理
知ってましたか? タッチパネルと、その方式
iOSアプリ開発におけるマルチタッチイベント
iOSでマルチタッチイベントを処理するメソッド
Page2
「UIResponder」のメソッドを実際に使ってみよう
反射神経測定iPhoneアプリを作ろう
マルチタッチイベントを制する者はiOSアプリ開発を制す



 Smart&Social フォーラム トップページへ



Smart & Social フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Smart & Social 記事ランキング

本日 月間