UICollectionViewをCompositionaLayoutで実装し、コードでUIを作成した時の話。
きっかけはUIViewにTapGestureをつけても反応しない・・・
UICollectionViewのCellの中に配置されているUIViewに対して、UITapGestureRecognizerを設定し、タップ動作を行えるようにしました。
しかし、タップは反応せず・・・
「あれ?」他に設定が必要だったかな・・・
とか思って悩んでいました。
見た目も普通に見えており、特に問題ないように思っていました。
しかし、見た目に騙されてはいけませんでした・・・
このように表示されていたので、気づきませんでした。
色々試して確認していると、気付きました・・・
Cellの高さが足りてない!
どういう事かといいますと、見た目はCellの中身が全部入っているように見えるし、正常なのだと思っていました。
しかし、実際はこのような状態になっていました。
コードのみでレイアウトを作成し、AutoLayoutを使用してViewを配置していました。
その際に、Cellの高さを子要素に合わせて指定していなかった事により、実際の高さが反映されていなかったのです_| ̄|○ il||li
「え?見えてるやん。なんで??」
と思ってしまいましたが、そういうモノなのですね。
そして、タイトルに記載したように、タップが効かない。
これの原因が、このCellの高さが実際の高さに合っていないことによるものでした。
このように2個目のUILabelはCellの範囲を超えています。
見えてますけどね。|д゚)チラッ
見えているが、Cellの高さは超えて配置されている。
そのため、2個目のUILabelのタップが動作しません。
1個目のUILabelも、1個目のUILabelにタップ動作を付けた場合、Cell内に収まっている部分(1個目のUILabelの上の方)はタップが反応します。
しかし、下の方は反応しません。
このような現象になります。
見た目が正常なだけに、なぜタップが反応しないのか?原因を理解するのに時間がかかってしまいました・・・
正常に動作するために書いたコード
class CustomCellName: UICollectionViewCell {
let label1 = UILabel()
let label2 = UILabel()
override init(frame: CGRect) {
super.init(frame: frame)
label1.text = "label1"
label2.text = "label2"
label1.translatesAutoresizingMaskIntoConstraints = false
label2.translatesAutoresizingMaskIntoConstraints = false
label1.addSubview(captionLabel)
label2.addSubview(bodyLabel)
label1.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16).isActive = true
label1.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 16).isActive = true
label1.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -16).isActive = true
label1.heightAnchor.constraint(equalToConstant: 200).isActive = true
label2.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16).isActive = true
label2.topAnchor.constraint(equalTo: label1.bottomAnchor, constant: 16).isActive = true
label2.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -16).isActive = true
label2.heightAnchor.constraint(equalToConstant: 200).isActive = true
// この記述でCellの高さを子要素に合わせている
contentView.bottomAnchor.constraint(equalTo: label2.bottomAnchor).isActive = true
}
}
説明に必要なコードのみ記載してます。
こちらのようなコードで最終的にレイアウトしました。
Cellの高さつけるために、UILabelの下部分にCellの下部がくるように指定しています。
これで配置されているUILabelすべてのタップが正常に動きました。
ちなみに、間違った記述の時に変な動きをしている部分がありました。
それを正常に理解していれば、もっと早く気付けたかも・・・
UICollectionViewを上にドラッグしてスクロールした時(指を画面の上の方に動かす動作)にCellが消えてしまう現象が発生していました。
後から考えると、Cellの高さが実際より小さいので、Cellの中に配置されているUILabelなどが見えている状態なのに、Cellの描画がされなくなった・・・のかな?と思われる現象が起きていました。
コメント