iPhone SDK開発のネタ帳 マルチタッチ対応

公開日: : 最終更新日:2010/04/20 iPad, iPhone ,

iPhone SDK開発のレシピにはいろいろ役に立つ内容があったので、同じようなことをブログに書いてみようの活動。

自作アプリおんぷちゃんでは、UIViewn上にUIButtonを置く形でピアノの鍵盤を実現しているが、今まではマルチタッチに対応していなかったので、和音に対応できていなかった。
今回、iPadアプリを作るにあたって、iPadはでかいので実寸に近い形で鍵盤を置くことができるので、今までのおんぷあてやおとあてだけではなく、普通に演奏できるモードも用意したいと思った。
実際にはiPadのグランドオープニングには全く間に合わなかったが、その後も細々と開発を続けている。

で、困っていたのは UIViewの上に複数のUIButtonを置いて、そのUIButtonを複数同時に押しても、どうやらマルチタッチにならない。UIButtonのtouchesBeganやtouchesMovedに [self.nextResponder touchesBegan:touches withEvent:event] を入れても superview にはマルチタッチとして渡らない。

で、今朝調べていたところようやく原因と思われるものを発見。
Apple のこのページに日本語で詳しく書かれていた。

ページの最後の方に、「ところが、マルチタップやマルチタッチは、それらが最初に発生したサブビューに関連付けられているため、スーパービューではこれらのタッチを受け取ること ができません。すべての種類のタッチを確実に受け取れるようにするには、スーパービューでhitTest:withEvent:を オーバーライドして、サブビューではなく自分自身を返すようにします。」と書かれている。

そこで、下記コードを入れてみたところ UIButton にはタッチ情報が渡らなくなり、UIViewの方でマルチタッチを検知できるようになった。

 - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
  if(CGRectContainsPoint(self.bounds, point)) { return self; } 
  return nil; 
} 

これにより、UIButtonが反応しなくなるので、CGRectContainsPoint()などを使ってヒットテストを行って、ボタンを手動でハイライト状態にする必要がある(UIButtonのインスタンス変数 highlighted に YES を入れる)。

UIViewのtouchesBegan:やtouchesMoved:にはUITouchがセットとして複数来るようになるので、ループを回して適切にハンドルする必要がある。

無為空間さんのページも参考にさせてもらいました。

追伸

hitTest:withEvent を使うようになってから、どうもアプリの挙動がおかしいと思っていたら、hidden プロパティを YES にした UIView のhitTest:withEvent が呼ばれていた。これはバグではないのか?これを避けるために、hitTest:withEventの中で、hidden プロパティの値をチェックして、hiddenがYESであればnilを返すようにして回避した。

iPhone SDK開発のレシピ―113個のレシピで学ぶiPhoneアプリ開発の極意
iPhone SDK開発のレシピ―113個のレシピで学ぶiPhoneアプリ開発の極意
秀和システム 2010-03
売り上げランキング : 3758

Amazonで詳しく見る by G-Tools

関連記事

no image

[iOS SDK] CGRect 関連の便利機能

CGRect を使っていていつも忘れて調べてしまうのでメモしてみる。 CGRect の変数を拡大・

記事を読む

[WatchKit] Apple WatchアプリをRejectされた話

Apple Watch はいつの間にか電池がかなり減っていることが多く、いつどのように減っているか知

記事を読む

no image

SHIELD iShell iPhone 4 用ケース購入

奥さんのiPhone 4用に SHIED iShell iPhone 4 シェルカバーを購入。Ama

記事を読む

no image

iPhone SDK勉強会

iPhone 開発の勉強会をしよう、ということになったので、それ向けにメモを書いてみる。相手はいろい

記事を読む

no image

[iOS SDK] QuickDialog を使ってみた

iOS オープンソースライブラリ徹底活用 菊田剛著 秀和システム | DevCafeJp で紹介さ

記事を読む

[iOS SDK] Simulator で Save Screenshot するとクラッシュ

「libswiftFoundation.dylib プラグインの使用中に Simulator が予期

記事を読む

no image

Xcode 設定しておくと便利なカスタマイズいろいろ

以前から Xcode はもう一歩使いにくいと思っていたが、iPhone アプリで稼げるのか でカスタ

記事を読む

no image

Invalid EvernoteSession で落ちる問題に遭遇

EverLearn アプリのバージョンアップ版を作成したのでテストをしていたところ、iOS5 で起動

記事を読む

no image

iPhone SDK 3.1.2 のお知らせ

Appleより、iPhone SDK 3.1.2 のお知らせが来た。 3.1.2 はバグフィックスリ

記事を読む

Siri Shortcuts に対応

正月休み中なので、ブログ記事が書きやすい。毎年この時期だけはよくブログを書いている気がする。

記事を読む

Comment

  1. amy より:

    はじめまして、amyと申します。

    私は、UIButtonを複数配置したのですが、6つ以上同時押しをすると
    挙動がおかしくなりました(押された状態で止まる)
    ネットで調べていた所、こちらのサイトにたどり着きました。

    hitTest:withEventを使い、UIButtonのインスタンス変数 highlighted を YESに設定し、
    再び6つ以上同時押しをすると、やはり同じエラーが発生しました。

    tokentokenさんは同じようなことはありませんでしたか?

  2. admin より:

    ちょっと調べてみたところ、iPhone が認識するマルチタッチの最大数は5であるようです。

    http://stackoverflow.com/questions/1202484/how-to-force-iphone-ipod-touch-to-handle-more-than-5-touches-at-the-same-time

    なので、6つ目でエラーが発生するのは仕様なのかも知れません。

    私はiPadで上記を実装していますが、iPadは11点まで認識できるという記事があったので、この制限にはひっからなかったようです。
    (全部の指を使ってひいても10点なので遭遇しなかった)

  3. amy より:

    返信ありがとうございます。

    3つまで同時押しをできるようにしたかったのですが、
    このエラーのせいで、困っていおり、質問しました。

    先ほど、私も調べましたが、iPhone が認識するマルチタッチの最大数は5みたいなので、
    エラーは仕様の可能性が大ですね。

    ただ、試しにiPhone版のおんぷちゃんの方(先ほどDLしました^^)で、
    同時押しをしてみましたが、特に問題ないようなので、
    私のプログラムが何か悪いだけのかもしれません^^;

  4. amy より:

    すいません。

    どうやら、6つ目のタッチでエラーが発生した時、
    highlighted を NOにする処理をしていなかったのが原因でした^^;
    highlighted がずっと YES状態になってただけです。

    6つ目がタッチされた時、touchescancelledが呼び出されるので、そこでhighlighted を NOすれば良かっただけです。
    お騒がせしました。

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

[Xcode] Interface Builder でControl+ドラッグでOutletが作成できない

たまにInterface Builder でUI作っているとはまるの

Ember Mug用のふたを買ってみた

Ember Mug Lid 2022年あけましておめでとうござ

Google Search Console の利用を開始してみた

YouTube DATA API (iOS Quickstart  

Xcode 13.1 アップデート

Apple、統合開発環境「Xcode 13.1」をリリース:Code

watchOS8 アップデート内容

この前購入した Apple Watch SE は watchOS 7

→もっと見る

PAGE TOP ↑