UITapGestureRecognizer Not Working

魚ー うおー 浜った!!

iOSでラベル(UILabel)にタップ認識(UITapGestureRecognizer)を追加しようとして

検索するとだいたいラベルのuserInteractionEnabledをYESにしろっていうのが出てくる。そんなの知ってるC。。。素人じゃあるまいし。素人だけど

で、最初に書いてたコードがこれ。1~3までの回答が書かれたラベルエリアがあって、誤った回答をタップするとaddGestureRecognizerした処理が実行されたい、という意図

試してみても動かない

[cpp]
UITapGestureRecognizer *wrongAnswerRecognizer = [[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(wrongAnswer:)];
wrongAnswerRecognizer.numberOfTapsRequired = 1;

int correct_answer = [[self.entity valueForKey:@"correct_answer"] integerValue];
if (correct_answer == 1) {
[label2 addGestureRecognizer:wrongAnswerRecognizer];
[label3 addGestureRecognizer:wrongAnswerRecognizer];
} else if (correct_answer == 2) {
[label1 addGestureRecognizer:wrongAnswerRecognizer];
[label3 addGestureRecognizer:wrongAnswerRecognizer];
} else if (correct_answer == 3) {
[label1 addGestureRecognizer:wrongAnswerRecognizer];
[label2 addGestureRecognizer:wrongAnswerRecognizer];
}
[/cpp]

この間にいろんなヘンな事を試すわけです。ラベルの境界線が重なりあって、タップが認識されていないのでは?って疑ってボーダー出してみてラベルの大きさとか位置とか確認したり。もしかしてラベルの下のビュー(superview)のuserInteractionEnableもYESにしないとダメなの?とか。結局イライラして画面連打してたら、3番目の回答をタップしたら処理が実行された!!

デバッグ中の画面の正解回答は2番。ずっとデバッグで1番の不正解ばかり確認してたのでした

そして、修正したコードがこちら

[cpp]
int correct_answer = [[self.entity valueForKey:@"correct_answer"] integerValue];
if (correct_answer == 1) {
[label2 addGestureRecognizer:[[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(wrongAnswer:)]];
[label3 addGestureRecognizer:[[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(wrongAnswer:)]];
} else if (correct_answer == 2) {
[label1 addGestureRecognizer:[[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(wrongAnswer:)]];
[label3 addGestureRecognizer:[[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(wrongAnswer:)]];
} else if (correct_answer == 3) {
[label1 addGestureRecognizer:[[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(wrongAnswer:)]];
[label2 addGestureRecognizer:[[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(wrongAnswer:)]];
}
[/cpp]

同じインスタンスを複数のラベルに指定すると、どうやら後から追加した方にもっていかれるようです。そんなもんで、タップ認識オブジェクト(UITapGestureRecognizer)は必ずView毎にインスタンス化する必要があるようです

知っていれば当然のような事に見えるけど、知らないとハマるかもしれないようなシチュエーション。意外とこういう地味な事に数時間費やしちゃう場合とかある

cruxbook app updates

http://cruxbook.comのiPhoneアプリの改修を少ししました

いま審査待ちになっているv1.0.2ではジムマップ及び登録ジムのデータの更新がリアルタイムにネットワーク経由で行われるようになります。当初は、登録依頼があればその都度更新ファイルか何かを用意して、都度新しいバージョンとしてリリースすれば良いかと思っていました。しかし、アプリをリリースした後のバージョンアップデートにおいても米アップル本社の審査が発生してしまうため、早くても1週間サイクルでしかアプリの更新が出来ないことが分かりました。それに、毎回ジム更新用のファイル作ったりするのも面倒くさかったので、いっその事リアルタイムにしちゃえ、という事で実装しました。リリース後すぐに何件か新規ジム登録依頼があったので、そういったうれしい依頼にはやはり迅速に対応したいですしね

v1.0.3では課題の検索結果一覧、課題の詳細をUIWebViewでネットワーク経由(つまりブラウザみたいな形ですね)で表示している部分を改修。とりあえずダミーの情報(Placeholder)を表示して、バックグラウンドでデータをダウンロードして、表示を更新、そして画像はローカルファイルにキャッシュ。これにより検索まわりの表示がモッサイ感じがなくなりました。サクサク動きます。後々検索結果が増えるとヤバイ感じになりそうだったので早々に対応

iOSのテーブルリスト表示(UITableViewCell)って画面に表示される度に呼び出されるんですね。例えば、検索結果としては20行あったとします。画面内に4行しか表示されない場合は、とりあえずその4件を表示するための情報が処理されます。ユーザーがスクロールして違う行を表示すると、当然それらの行が処理されます。しかし、ユーザーがスクロールなどをして最初の4行に戻ったとします。これもまた表示用の処理がされます。このあたりは表示する内容によって工夫はできますが、UIWebViewを使っている場合は、なんとその都度Webサーバにリクエストが飛んでいくことになる。。。

この対策にはアップルのドキュメントにもハウツーがあったので、ほぼそのまま丸パクリしました

LazyTableImages

It begins by loading the relevant text from an RSS feed so the table can load as quickly as possible, and then downloads the images for each row asynchronously so the UI is more responsive.

Google Analytics SDK for iOS v2 (Beta)

これは便利。アプリ内でも細かな動作を解析できます(逆に言うと、あなたは細かな動作を解析されています)

Google Analytics SDK for iOS v2 (Beta) – Overview
https://developers.google.com/analytics/devguides/collection/ios/v2/?hl=ja

しかし組み込むのにGAITrackedViewControllerを継承しなくてはいけなくて後から組み込むのは結構面倒くさかったです

何かDelegateでは実装できない処理とかあるのかな。そこまでiOSに踏み込んでないので分からないけど