フォトシンス エンジニアブログ

株式会社Photosynth のテックブログです

UICollectionView vs UITableView

この記事は Akerun Advent Calendar 2020 - Qiita の21日目の記事です。

Webエンジニアのbeginer_rider - Qiitaと申します。 主にiOSアプリ開発を担当としています。

はじめ

iOS開発者の皆さんにはよくある話と思いますが、リスト画面を作るときに、UICollectionViewとUITableViewのいずれを検討することがあったと思います。 リストの要素数、セルの色や表示名を動的に変更する中でどれがよいか、悩んだ方も多いのではないでしょうか。 そんな方々に少しでも助けになればと思い、UICollectionViewとUITabeViewのそれぞれのメリデメをご紹介させていただきます。 プチ読み物的なものとしてご一読ください。 ※あくまで個人的観点でのメリデメとなりますので、気になった方がいらっしゃればご指摘いただけますと幸いです。

UIColletionViewのメリデメ

メリット

UICollectionViewLayoutを利用することで、セルのレイアウトを変更することが可能

prepareメソッドをoverrideすることで、セルのレイアウトを変更することができます。 UICollectionViewLayoutのサブクラス、UICollectionViewFlowLayoutにはitemSizesectionInsetなど、セルのUIを変更するのに役立つ様々なプロパティを備えています。 加えて、セルだけでなくHeaderFooterのレイアウトを変更することができます。

また、他にもUICollectionViewFlowLayoutだけでなく、UICollectionViewLayoutAttributesUICollectionViewLayoutInvalidationContextなどのレイアウトを調整するためのクラスが用意されています。 そのため、柔軟にレイアウトを組むことができます。(1行ごとに表示する要素を変えるなど)

アニメーションのあるセルの挿入や削除を行うことができる

performBatchUpdateクロージャの中でreloaddeleteの処理を行うことで、一律でアニメーションのアップデートを行うことができます。 例えば、5つあるリストの1つ目を削除し、1つ目に新規要素を挿入するなら、deleteinsertの処理を行うことで、実現することができます。

デメリット

セルの挿入や削除の制御に手間がかかる

performBatchUpdateクロージャの中で、制御対象とするセルに対して、IndexPathを設定する必要があります。performBatchUpdateでは処理の順番に関わらず、削除→挿入の順に処理が実行されます。この時、削除や挿入する対象のセルがなければエラーが生じてしまうため、設定するIndexPathを正しく選択しておく必要があるので、削除や挿入前後のセルの順番を把握しておく必要があります。 画面を回転させた場合、セルの再生成を行う場合においてもIndexPathを正しく洗濯しておく必要があるため、あらゆる場合で考慮しておく必要がありそうです。

UITableViewのメリデメ

メリット

シンプルなリスト画面を作成しやすい

UICollectionViewとは違い、リスト画面のみを想定して用意されているため、簡単なリスト画面を作成する際には利用しやすいです。 リストに表示したい要素にSwitchButtonToggleBarなどを複数表示するためにそれぞれのセルを作成する必要はありますが、セルを表示する順番さえ決めておけば、あとはシステムがよしなに処理してくれるので楽です。

レイアウトの更新処理はlayoutIfNeededでなんとかなる

UITableViewのセルを更新完了の際にlayoutIfNeededを呼ぶだけで更新を完了させることができ、非常に楽です。ただ、他にreloadDatalayoutSubViewsなどのセルを更新するメソッドがありますが、こちらは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