この記事は Akerun Advent Calendar 2020 - Qiita の21日目の記事です。
Webエンジニアのbeginer_rider - Qiitaと申します。 主にiOSアプリ開発を担当としています。
はじめ
iOS開発者の皆さんにはよくある話と思いますが、リスト画面を作るときに、UICollectionViewとUITableViewのいずれを検討することがあったと思います。 リストの要素数、セルの色や表示名を動的に変更する中でどれがよいか、悩んだ方も多いのではないでしょうか。 そんな方々に少しでも助けになればと思い、UICollectionViewとUITabeViewのそれぞれのメリデメをご紹介させていただきます。 プチ読み物的なものとしてご一読ください。 ※あくまで個人的観点でのメリデメとなりますので、気になった方がいらっしゃればご指摘いただけますと幸いです。
UIColletionViewのメリデメ
メリット
UICollectionViewLayoutを利用することで、セルのレイアウトを変更することが可能
prepare
メソッドをoverrideすることで、セルのレイアウトを変更することができます。
UICollectionViewLayoutのサブクラス、UICollectionViewFlowLayout
にはitemSize
やsectionInset
など、セルのUIを変更するのに役立つ様々なプロパティを備えています。
加えて、セルだけでなくHeader
とFooter
のレイアウトを変更することができます。
また、他にもUICollectionViewFlowLayoutだけでなく、UICollectionViewLayoutAttributes
やUICollectionViewLayoutInvalidationContext
などのレイアウトを調整するためのクラスが用意されています。
そのため、柔軟にレイアウトを組むことができます。(1行ごとに表示する要素を変えるなど)
アニメーションのあるセルの挿入や削除を行うことができる
performBatchUpdate
のクロージャの中でreload
やdelete
の処理を行うことで、一律でアニメーションのアップデートを行うことができます。
例えば、5つあるリストの1つ目を削除し、1つ目に新規要素を挿入するなら、delete
とinsert
の処理を行うことで、実現することができます。
デメリット
セルの挿入や削除の制御に手間がかかる
performBatchUpdate
のクロージャの中で、制御対象とするセルに対して、IndexPath
を設定する必要があります。performBatchUpdate
では処理の順番に関わらず、削除→挿入の順に処理が実行されます。この時、削除や挿入する対象のセルがなければエラーが生じてしまうため、設定するIndexPath
を正しく選択しておく必要があるので、削除や挿入前後のセルの順番を把握しておく必要があります。
画面を回転させた場合、セルの再生成を行う場合においてもIndexPath
を正しく洗濯しておく必要があるため、あらゆる場合で考慮しておく必要がありそうです。
UITableViewのメリデメ
メリット
シンプルなリスト画面を作成しやすい
UICollectionViewとは違い、リスト画面のみを想定して用意されているため、簡単なリスト画面を作成する際には利用しやすいです。
リストに表示したい要素にSwitchButton
やToggleBar
などを複数表示するためにそれぞれのセルを作成する必要はありますが、セルを表示する順番さえ決めておけば、あとはシステムがよしなに処理してくれるので楽です。
レイアウトの更新処理はlayoutIfNeeded
でなんとかなる
UITableViewのセルを更新完了の際にlayoutIfNeeded
を呼ぶだけで更新を完了させることができ、非常に楽です。ただ、他にreloadData
やlayoutSubViews
などのセルを更新するメソッドがありますが、こちらはUITableView全体を更新してしまい、処理の遅延に繋がることがあるので、利用するには向いてないです。
デメリット
セル数の更新操作が挿入と削除のみ
ネイティブライブラリから提供されているUITableViewのセルに対する操作は挿入と削除のみとなっています。 そのため、セルの移動に関してはUITableViewDelegateとUITableViewDataSourceで定義されている下記メソッドを実装する必要があり、手間がかかります。
・UITableViewDelegate
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle
・UITableViewDataSource
func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath)
最後に
いかがでしたでしょうか。検討する際の一助となれば幸いです。 UICollectionViewとUITableViewにはそれぞれの特徴があるので、うまく使い分けてみてください! 最後までご覧くださりありがとうございました。
株式会社フォトシンスでは、一緒にプロダクトを成長させる様々なレイヤのエンジニアを募集しています。 hrmos.co
Akerun Proの購入はこちらから akerun.com