2015年3月19日木曜日

オブジェクトのタッチ位置検出とドラッグ

単純に位置を得る場合
タッチイベントの検出は、以下のメソッドで。
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    CGPoint dustPoint = [[touches anyObject]locationInView:self.view];
}

[touches anyObject]
はNSSetからUITouchのインスタンスを取り出している。よくわからんけど、そうなるの。
んで、
[[touches anyObject]locationInView:self.view];
によって、自分のviewの座標の位置に変換している。これもよくわからんけど、そうなるからいいの。
よって、dustPointを見ればタッチした位置がわかる。

touchesBegan:〜はタッチした瞬間の位置なので、
指を離した時、
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
タッチしたまま指を動かした時、
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
はそれぞれ別メソッドで。


オブジェクトをドラッグしたりする場合
複数のカスタムクラスによるUIオブジェクトの、タッチしたものだけドラッグしたりする場合は、delegate使う。
カスタムクラス側でdelegateの記述を書く。
例)
Dust.h
@protocol DustDelegate
- (void)dustTouchMoved:(Dust *)dust;
@end

@interface Dust : UIImageView
@property (weak) id delegate; //独自delegate
@property (assign) CGPoint touchPoint; //位置
@end

Dust.m
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    //タッチされた位置をpropertyに入れてdelegateされる
    _dustPoint = [[touches anyObject]locationInView:nil];

    if ([self.delegate respondsToSelector:@selector(dustTouchMoved:)]) {
        [self.delegate dustTouchMoved:self];
    }
}
プロパティのtouchPointにタッチ位置を入れておいてやれば、delegateで渡された先でも位置がわかる。
locationInView:nil
nilになってることに注意。self.viewもしくはself(viewを持たない部品の場合)のままでは自分のUIの左上からの座標になってしまう。

ただし、nilを指定したまま画面の縦横を変えると(landscape、portrate)座標が左下からになってしまうという情報も? 自分で試してみたところならなかったみたいだけど、念のため注意。

参考サイト:Cocoaの日々

んで、delegate先に以下のメソッドを書いておけば、指の位置にズルズルとUIオブジェクトがくっついてくるぞ。
(カスタムクラスdustをallocした際に、dust.delegate = self; とやっとくのは当然)
- (void)dustTouchMoved:(Dust *)dust
{
    //property dustPointにタッチされた位置が入ってる
    dust.center = dust.touchPoint;
}

0 件のコメント:

コメントを投稿