はじめに
UICollectionView
を使っている際に、Cell以外の部分をタップした際に処理を動かしたい事があったので、その際に使用した方法を記載します。
環境
Xcode11
Swift4.2
Cellのタップを検知する
UICollectionView
でCellのタップを検知する際は、UICollectionViewDelegate
プロトコルを使用する方法が一般的だと思います。
extension ViewController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("Cellがタップされた!")
}
}
Cell以外のCollectionView内のタップを検知する
UICollectionViewDelegate
プロトコルを使用することでCellのタップを検知する事ができましたが、今回のようにCell以外のCollectionView
をタップした際に動かしたい処理がある場合は別の方法を取ります。
今回自分は、UITapGestureRecognizer
を使用しました。
UITapGestureRecognizer
は、UIGestureRecognizer
の1つで、画面のタップを1度だけ認識してくれます。(連続して認知する場合はUILongPressGestureRecognizer
を使用します)
名前が似ているのでわかりにくい…
まずはUIGestureRecognizerDelegate
プロトコルを使用し、Viewにインスタンスを追加します。
class ViewController: UICollectionViewController, UIGestureRecognizerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// UIGestureRecognizerのインスタンスを作成
let tapGesture:UITapGestureRecognizer = UITapGestureRecognizer(
target: self,
action: #selector(ViewController.tapped(_:)))
// デリゲートをセット
tapGesture.delegate = self
// Viewにインスタンスを追加
self.collectionView?.addGestureRecognizer(tapGesture)
}
この際、インスタンスのアクションには、タップされたときに期待する動作を記述します。
@objc func tapped(_ sender: UITapGestureRecognizer){
print("CollectionViewがタップされた!")
}
しかし、このままだとCellをタップした際にもイベントが発火し、メソッドが呼び出されてしまいます。
そのためメソッド内に、Cellがタップされたかどうかを判断する処理を追記します。
@objc func tapped(_ sender: UITapGestureRecognizer){
// indexPathForItemメソッドを使い,cellのindexを取得できない場合はタップされた場所がcellでないと判断
guard let index = self.collectionView?.indexPathForItem(at: sender.location(in: self.collectionView)) else {
print("Cellではないところがタップされた!")
}
}
以上です!