40歳からのキャリアチェンジ

20代はエンジニア・PM、30代はWeb系エンジニア向けのキャリアアドバイザー。40代の今はフリーランスで開発含めて色々やってます。技術ネタとしてはRuby/RailsとJavaScript関連あたり

tableViewに後から割り当てたイベントが複数発火されないようにするためには

ここ数日はまっていたことがあり、もしかしたら似たようなことでハマるひとがいるかもしれないので、まとめておきます

実装したかったこと

左上のボタンをタッチした時に、メインの投稿一覧画面がスライドされるようなUIのアプリを作ってます

標準状態の画面

f:id:h5y1m141:20121127074333p:plain

スライドした時の画面

f:id:h5y1m141:20121127074401p:plain

スライド状態で、メインの投稿一覧画面から詳細画面へ遷移させたくないので、tableViewのclickイベントを無効にしたいと考えていました

最初考えた実装方法

何らかのボタンがタッチされた時にtableView.addEventListenerとtableView.removeEventListenerを設定すればいいのかと思い、以下の様な実装をしていました

CoffeeScriptのサンプルソースコード。ダメなパターン

table = Ti.UI.createTableView
assignBtn = Ti.UI.createButton
assignBtn.addEventListener('click',()->
  table.addEventListener('click', () ->
  )
)
removeBtn = Ti.UI.createButton
removeBtn.removeEventListener('click',()->
  table.removeEventListener('click', () ->
  )
)

こんな感じで実装すると、スライドのオン・オフを複数実施した後に、tableViewをタッチすると、

投稿一覧画面→詳細画面→詳細画面→(以下繰り返し)

という感じで複数イベントが発火される状況になっていました。

上記ではうまくいかなかったので以下にて解決

最初は、Titaniumのバグなんじゃないかと一瞬疑ったのですが、ひげろぐさんのaddEventListenerで登録した処理が複数回実行される問題というエントリをたまたま見つけて、これを読んでるうちに、自分の実装方法が間違ってるんだろうなという考えにいきつきました。

「titanium tableview click event false」というキーワードでぐぐったら、本家のQ&AにMultiple click on row will fire event multiple timesという内容のものを見つけました。

これ見ててtableViewに touchEnabled というプロパティがあるのを今更知りました・・・ 

CoffeeScriptのサンプルソースコード。意図した動作をするパターン

table = Ti.UI.createTableView
assignBtn = Ti.UI.createButton
assignBtn.addEventListener('click',()->
  table.touchEnabled = true
  )
)
removeBtn = Ti.UI.createButton
removeBtn.removeEventListener('click',()->
  table.touchEnabled = false
  )
)

教訓

Titanium MobileのAPI Reference で関連するものがないかもっとしっかり調べるべきですね。