UILabelやUIImageViewのタッチイベントを取得する

list このエントリーをはてなブックマークに追加

iPhone プログラミングの中で、ボタンのクリックイベントは簡単に取れるのですが、ラベルや画像のクリックイベントが手軽に取れません。いくつか調べると、UITapGestureRecognizer を使うか、touchesEnded メソッドをオーバーライドするか、という方法があるのですが手軽でもないので。

iphone – How can I determine if a UILabel was touched? – Stack Overflow
http://stackoverflow.com/questions/2539380/how-can-i-determine-if-a-uilabel-was-touched
UILabelのタッチイベントを検出する方法 ? 拡張現実ライフ
http://akio0911.net/archives/3419

どうやら、tag を使うと一番手軽そうなので紹介しておきます。

最初に、viewDidLoad の中で tag を設定しておきます。userInteractionEnabled プロパティの値を YES にしておかないとイベントが発生しなくなるので注意してください(何故イベントが発生しないのかは不明)

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
    labelCommand.userInteractionEnabled = YES;
    labelCommand.tag = 100;
    imageLogo.userInteractionEnabled = YES;
    imageLogo.tag = 101;
}

「100」とか「101」とかは、適当な値で十分です(0は初期値なので駄目)。
#define しても良いのですが、使い捨てなのでそのまま。

touchesBegan イベントをオーバーライドします。ViewController 上にあるイベントをタッチイベントを全てフックするので、これから目的のオブジェクトを探し出します。

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [[event allTouches] anyObject];
    if ( touch.view.tag == labelCommand.tag )
        [self clickCommand:labelCommand];
    else if ( touch.view.tag == imageLogo.tag )
        [self clickLogo:imageLogo];
}

ここで、touch.view.tag と、ラベルの tag の値とを比較します。本来は switch で比較するのが良いのでしょうが、面倒なので(苦笑)そのまま tag の値と比較しています。実は、こうすると #define が必要なくなるのです。

イベントは、ボタンのクリックイベントのように書きたいため、ViewController 上で定義した clickCommand を呼び出します。一応、sender はラベルや画像オブジェクトそのもの渡します。

-(IBAction)clickCommand:(id)sender 
{
    NSLog(@"in clickCommand");

}
-(IBAction)clickLogo:(id)sender 
{
    NSLog(@"in clickLogo");
}

こんな風に、あたかもボタンと同じようにしておきます。こうすると、クリックイベントみたいで分かり易いですよね。

実行すると、普通のボタンと同じようにログが出力されます。

カテゴリー: Objective-C パーマリンク

UILabelやUIImageViewのタッチイベントを取得する への6件のフィードバック

  1. のコメント:

    大変助かりました。ありがとうございます。Interface Builderでいろいろ試しても、出来ないから、このサイトを見て、見事に解決できました。

    • masuda のコメント:

      タッチイベントだけを取りたい場合は、touchesBegan イベントを拾うのが楽なのでお試しを。ただし、通常のボタンのように touch が release されたとき(指を離した時に)イベントを拾いたい場合は、別途工夫が必要みたいです。
      ちょっと、そこまでは調べておらず。。。

  2. tomiflu のコメント:

    UILabel のタップイベントを取得できずに困っていました。
    大変助かりました。ありがとうございます!

    • masuda のコメント:

      なぜ Windows では存在するタップイベントが、Apple にはないのか? … と考えても始まらないので(苦笑)、ひとまず方法だけを晒した次第です。iPhone/iPad はタップ中心(マウスクリックではない)ので、そのあたり Windows との違いで四苦八苦。
      お役に立てたようでなによりです w

  3. aki のコメント:

    スクロールビューの上の UILabel だと、タップイベントが発生してくれませんでした。残念。。。

    そういう場合は
    http://php6.jp/iphone/2011/11/11/uilabel%E3%82%84uiimageview%E3%81%8C%E5%BF%9C%E7%AD%94%E3%81%97%E3%81%AA%E3%81%84/
    がよいようです。
    というか、こちらの方が実装量少ないかも (^^;

    • masuda のコメント:

      コメント Thx です。
      UITapGestureRecognizer の挙動に慣れていないといまいちだったので、tag にしました。スクロールビューだと別の実装が必要みたいですね。
      このネタ元になった電子書籍の話がぽしゃってしまったので、ここの操作は打ち止め状態で…たぶん、今度作るときは3枚のUIViewを切り替えて100ページ超の電子書籍になるかなと。この時は、パンフレットを想定していたので、十数ページをスクロールビューで切り替えるつもりだったのですが。

コメントは停止中です。