총 3개의 섹션(Section)을 가지는 collectionView를 구현해보았고
생각보다 자주 놓치는 부분이 있어서 해당 내용을 정리해보았습니다.
collectionView의 DataSource를 생성하는 과정에서 필수 메서드인
func collectionView( ... , cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
위 내용을 구현하다보면 자연스럽게 아래와 같이 dequeue 코드를 작성하게됩니다.
guard let cell = collectionView.dequeueReusableCell(
withReuseIdentifier: 'Cell'.identifier, for: indexPath) as? 'CustomCell' else {
return UICollectionViewCell()
}
말그대로 dequeue(대기열에서 빼냄)에서 UICollectionViewCell
을 재사용한다는 뜻이 내포되어있기에 초기화까지 이루어진다고
생각할 수 있지만 직접 실행해보면 잔여물? 초기화되지 않고 남으면서 셀의 재사용성에 대해 문제가 발생합니다.
아래의 예시를 보면 가격 및 뱃지가 보여지는 UI에 이전에 없었던 가격과 뱃지가 나타나는 현상을 볼 수 있겠습니다.
View를 다시 사용할 수 있도록 준비하는 데 필요한 초기화(clean-up)를(을) 수행합니다.
요약 내용으로만 보아도 View를 초기화하는 역할을 수행하는 메서드이며
좀 더 자세한 내용을 정리해보면 아래와 같습니다.
- 그냥 호출해서 사용하면 아무런 동작이 없음으로 해당 메서드를 재정의하여 사용합니다.
- CollectionView가 view의 사용을 위해 큐에서 빼는 경우,
해당 dequeue 메서드가 View를 코드로 반환하기 전에prepareForReuse()
메서드를 호출합니다.- 이 방법을 사용하여 View에 새 데이터를 할당하지 않습니다. 이는
DataSource
의 책임입니다.
🌐 공식문서: prepareForReuse() | Apple Developer Documentation - UICollectionReusableView
메서드의 원형은 아래와 같습니다.
override func prepareForReuse() {
super.prepareForReuse()
// 셀을 속성을 초기화 해주는 코드.
// (값을 할당하는 코드는 데이터소스에 작성합니다.)
}
재사용 되는 cell을 dequeue 할 때 이전에 사용 되었던 흔적이 남던 내용을 prepareForReuse를 통해 해결해보도록 하겠습니다.
private func prepareForReuse(stackView: UIStackView) {
stackView.subviews.forEach { view in
view.removeFromSuperview()
}
}
override func prepareForReuse() {
super.prepareForReuse()
foodImageView.image = nil
prepareForReuse(stackView: foodInformationStackView.foodPriceStackView)
prepareForReuse(stackView: foodInformationStackView.badgeStackView)
}
위와 같이 작성하여 시뮬레이션을 확인해보았더니 아래와 같이 잘 해결됨을 볼 수 있었습니다.
iOS) prepareForReuse() 사용해서 셀을 초기화해보자
[iOS] prepareForReuse란?
StackOverflow | What is the correct way to use prepareForReuse?
prepareForReuse() | Apple Developer Documentation - UITableViewCell