2012年1月26日木曜日

タッチイベントの発生仕方

UIView上、正確にはUIResponderでは、画面をタッチするとtouchesBegan/Moved/Ended/Cancelledイベントが発生する=メソッドが呼び出されるが、どういう状態のときにどう送られてくるかは資料がなかった。

とりあえず解ったのは以下の通り。

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

(1)基本はBegan(押したとき)->Moved(移動中)->Ended(指を離した)の順で呼び出される
ただし、移動が少ないときは Movedは来ない場合もある。
また、複数タッチしたときは、その都度Beganが発生する。

(2)同点タッチではタッチイベントは発生し続けない
逆に言えば、イベントは座標もしくは押下状態が変化したときのみ発生する。
タッチ中かどうかは上記イベントの発生状況によって判定するしかない。

(3)タッチが何本指なのかは[touches count]で取得出来る
iOS5ではGestureRecogniserでシングル/マルチ他の判定を行ってくれるようだが、iOS4までは処理内でこれを数えて処理を分けるしかない。

(4)マルチタッチは[touches count]==2だけで処理するとたぶん半分は抜けてしまう
実は人間の指の動作はそんなに厳密ではないので、Began*2という押され方をすることもある。それもマルチタッチと見なす方が「親切」だと思う。
私の作ったアプリはそうしている。
began(cnt=1)->moved(cnt=1)->began(cnt=1)->moved(cnt=2)なんてパターンもあるので注意。

(5)マルチタッチの場合、touchesで返ってくる座標情報の順番は不定
押下順ではない。従って、スライドの移動方向を得ようとするときには、全ての座標を読み取って、正しい組み合わせで算出する必要がある。
 (6)ストロークしたまま画面外に出る・中に入るときのbegin/endedの状態
    シミュレーター上
        外に出る    マウスクリックを離した時点でEnded(画面外座標を返している)
        中に入る    全て無視される(中に入っても検出されない)
    実機上
        外に出る    物理画面内なら、タッチを離した時点でEnded(画面外座標を返している)
        中に入る    全て無視される(中に入っても検出されない)
        iOS5では、スータスバーの位置から下ドラッグすると、Nortify画面が出てくる

まあ、他にもいろいろあるが、プログラムを組む上で最低限必要なのはこれくらいかと。
マルチタッチ時の座標の処理は結構面倒で、頭の体操になる。


「長押しはどう処理すんねん」とかあるかもしれないけど、それはいずれまた。

0 件のコメント:

コメントを投稿