🍎

[Swift]CollectionViewCellの再利用:prepareForReuse

2022/02/25に公開

経緯

CollectionViewのCellの内容が重複したり、意図した表示にならないことがあったので。

CollectionViewのCell再利用の仕組み

画面をスクロールしていくと、上のセルから消えていき、
下から新しいセルが表示されると思います。

よくあるCellの生成でこのようなコードがあります。

 let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)

Cellの再利用ということと紐づいているメソッドが、
dequeueReusableCell(withReuseIdentifier:)
以下公式の意訳です。

collectionViewに新しいセルを提供するように求められたら、
data sourceからこのメソッドを呼び出します。
このメソッドは既存のセルが使用可能な場合はそのセルをデキューする、
または以前登録したクラスまたはnibファイルに基づいて新しいセルを作成します。
既存のセルが再利用可能な場合は、
このメソッドは代わりにそのセルのprepareForReuse()メソッドを呼び出します。

https://developer.apple.com/documentation/uikit/uicollectionview/1618063-dequeuereusablecell

このように再利用可能なCellに関しては、prepareForReuse()がコールされます。
再利用の仕組みとしては表示されなくなったCellはqueueに入れておき、
新しいセルが表示されるときにqueueからセルを取り出すというイメージになります。
そうするとCell内のコンポーネントの値などが再利用時に残ってしまう場合があります。
この影響で経緯で書いたような挙動を引き起こします。
その解決策としてprepareForReuseでCellを初期化してあげます。

prepareForReuse

コールされるタイミングは上記で書いたように、
Cellの再利用可能と判断され、Cellがqueueから取り出される間際です。
そのタイミングでCell内のコンポーネントの値を初期化してあげます。
すると再利用時に残ってしまう原因でのセルのおかしな挙動の場合は、
1つの解消法になるかと思います。

 override func prepareForReuse() {
    super.prepareForReuse()
    label.text = ""
    imageView.image = UIImage(named:"")
}

Discussion