UICollectionViewDataSourceについて解説

はじめに

初めまして。JCBデジタルソリューション開発部の若林です。今年の春から社会人になり、研修として7月から3ヶ月間ReactでWebアプリケーションを作成して、その後10月から現在に至るまでSwiftでMyJCBアプリを開発しています。

先日、MyJCBアプリの開発で初めて新規画面の開発を担当しました。 新規画面にはUICollectionViewを利用しました。
今回は、新規画面を作成する過程で学んだUICollectionViewDataSourceについてご紹介します。

UICollectionViewとは

まず初めに、UICollectionViewの概要を簡単に説明いたします。 一言で表現すると、複数のアイテムを柔軟に並べて表示するための仕組みです。

具体例としては、iPhone標準の「写真」アプリなどで利用されています。 当社のMyJCBアプリでも複数の画面で活用しており、以下の画像はその一例です(なお、開発環境のものですので実際の画面とは一部内容が異なります)。

下記画像の横一列がUICollectionViewです。 そこに配置されているアイコンが入っている四角いボックスとテキスト(「コンシェルジュ」や「MyJCBPay」と書かれている)がUICollectionViewCellとなります。

このように、UICollectionViewでは「Cell」という単位でテキストや画像などの要素を表示します。

UICollectionViewDataSource

次に、本題であるUICollectionViewDataSourceについてご説明いたします。
UICollectionViewDataSourceは、一言でいうとUICollectionViewに表示するデータやCellを提供するプロトコルです。 具体的にはCellの数、表示するCellの構成等をUICollectionViewに提供しています。
UICollectionViewを実装する際は、必ずUICollectionViewDataSourceを実装しなければなりません。
では、なぜこのプロトコルが必要なのでしょうか。調査した結果、主に以下の2点が大きな利点であることに気づきました。

データ変更への柔軟な対応

UICollectionViewDataSourceでは、例えば下記のようなメソッドが定義されています。

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 3
    }

このメソッドの戻り値によって、UICollectionViewが表示すべきCellの数が決定されます。 たとえば、

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return apiResponseObject.count
    }

のように、APIレスポンスから取得した配列の要素数を返すことで、データに応じたCell数を反映できます。

メモリ効率の最適化

UICollectionViewでは大量のデータを扱う時にもメモリの使用量を抑えられる仕組みを持っています。その仕組みの中心となるのがCellの再利用です。

画面外にあるCellはReuse Queueという場所に格納されて、再度表示が必要になったタイミングで取り出して再利用します。この仕組みが無駄なCellの生成を控えてメモリの使用量を抑えています。

下記のメソッドでCellの生成と再利用をしています。

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
   let cell = collectionView.dequeueReusableCell(withReuseIdentifer: "cellIdentifier", for: indexPath)
   // 与えられたIndexPathでケース分けをしてCellごとにコンシェルジュのロゴやテキスト、 MyJCB Payのロゴやテキストを入れる。
   return cell
}

このcellForItemAtのメソッドが自分にとっては分かりづらかったため、イラストと具体例を使用して解説します。具体例には先ほどUICollectionViewで実装していると言った下記画像を使用します。

初期表示時

1回目の左スクロール後

2回目の左スクロール後

この時の動きは下記画像のようになります。

スクロールされて画面に新しいCellが必要になるたび、cellForItemAtメソッドが呼ばれます。そして画面外へ出たCellはReuse Queueの中に入れられます。Reuse QueueはwithReuseIdentiferで管理されており、同じwithReuseIdentiferを持つCellが再び必要になるとReuse Queueの中にあるCellを使用してCellを表示します。 つまりこのエリアでは、画面に表示されるCellの数(5個)と、スクロール時の画面表示をスムーズにするための予備のCell(前後1個ずつ合計2個)の7個だけを、メモリに保持すれば良いのです。

まとめ

この記事では、UICollectionViewとそのデータソースであるUICollectionViewDataSource、そして自分が理解しづらかったメソッドであるcellForItemAtについて解説しました。
特にcellForItemAtメソッドが自分は理解しづらかったため、この記事を書こうと考えました。この記事を読むことでcellForItemAtメソッドの理解が深まってくれたら嬉しいです。

終わりに

最後になりますが、JCBでは我々と一緒に働きたいという人材を募集しています。 詳しい募集要項等については採用ページをご覧下さい。
www.saiyo.jcb.co.jp

©JCB Co., Ltd. 20︎21