よくあるtapGestureを仕込んだとき、
同じViewに表示されている他のUIButtonやCellをタップしても認識されなくなったことはありませんか?
タップでキーボードを閉じる簡単な処理を書いたのですが、
CollectionViewCellへのタップ効かなくなってしまい、この問題について調べてみました。
なぜ他Viewのタップを認識しなくなるか
UIGestureRecognizeのリファレンスを読んでみると、
以下のプロパティがあります。
cancelsTouchesInView
A Boolean value affecting whether touches are delivered to a view when a gesture is recognized.
ジェスチャーが認識されたときのタッチがビューに配信されるかどうかに影響するブール値。
Discussion
When this property is YES (the default) and the receiver recognizes its gesture, the touches of that gesture that are pending are not delivered to the view and previously delivered touches are cancelled through a touchesCancelled:withEvent: message sent to the view. If a gesture recognizer doesn’t recognize its gesture or if the value of this property is NO, the view receives all touches in the multi-touch sequence.
このプロパティがYES(デフォルト)で、受信機がそのジェスチャーを認識すると、保留されているジェスチャーのタッチは、ビューに配信されず、以前に配信タッチはtouchesCancelledを通じて相殺される: withEvent :ビューに送信されたメッセージ。ジェスチャ認識は、そのジェスチャーを認識しないか、このプロパティの値がNOの場合、ビューは、マルチタッチシーケンス内のすべてのタッチを受信した場合。
(Google翻訳)
つまり、このプロパティのデフォルト値がtrueになっていまして、
gestureのないViewをタップしたつもりになっていても、キャンセルされていたようです。
解決
gestureを設定するときに、上記プロパティの設定を一行加えてあげることで解決します。
let tapGestureRecognizer= UITapGestureRecognizer(target: self, action: "tapGesture:")
tapGestureRecognizer.cancelsTouchesInView = false
cancelsTouchesInView プロパティにfalseを渡せばOK。
補足
UIGestureRecognizerのプロパティなので、
タップだけでなく諸々のgestureに使えます。
参考ページ
UITapGestureRecognizerとUICollectionViewが競合した場合
タップ認識
UIGestureRecognizer Class Reference