アプリを作成する上でほぼ100%登場するであろうUITableView。カスタムセルで実装する事も多いかと思います。
カスタムセルを作成する場合、
- Xibを使用したインターフェースビルダーでUIを構築
- コードベースで作成
の2パターンあるかと思います。
xibを使用する場合にはほとんど意識していなかったのですが、コードベースで作成する場合、思わぬところに落とし穴があったので、皆さんに共有したいと思います😄
addSubview(〇〇Label)
コードベースでパーツをsubviewに配置します。
一見、何の問題もないかのように見えます。
実際、この後にレイアウトの設定を行うことで、問題なく表示することが出来ます😆
しかし、僕が実際に経験したことなのですが、
- 下方向にスクロール
- 上方向スクロールして同じ場所に戻ってくる(セルの再利用が行われる)
- セルをタップする
すると、didSelectRowAtが機能しなくなるというバグが起きました😱
何が原因なのかも特定できずに、多くの時間を費やしてしまいました。
[結論] tableViewCellにはcontentViewが存在するため、contentView.addSubview(〇〇Label)とする
The content view of a UITableViewCell object is the default superview for content that the cell displays. If you want to customize cells by simply adding additional views, you should add them to the content view so they position appropriately as the cell transitions in to and out of editing mode.
説明がわかりづらいですが😅追加するだけでセルをカスタムしたい場合はContentViewに追加してね、という事のようです。
セルには編集モードも存在するため、contentViewに追加しないと編集モードの挙動なども意図しない挙動になりそうです。
実際にcontentViewにaddSubviewする事で上記のバグは改善されました。
ちなみにCollectionViewCellのドキュメントにはしっかり
Don’t directly add subviews to the cell itself.
と強調してselfに追加しないでね!!と書いてました。(tableViewCellにも書いておいて欲しかった🥲)