해당 화면은 collectionView를 활용하여 상품목록을 보여주는 화면입니다. 얼핏보면 segmented control을 터치하여 화면이 정상적으로 전환되는 것 같아 보입니다. 눈치 채셨을 수도 있지만 화면을 전환 할 때 마다 cell에 잠시동안 다른 상품의 썸네일이 보이다가 정상적인 사진으로 바뀌는 것을 볼 수 있습니다.
이런 현상이 발생하는 것은 collectionView가 cell을 reuse하기 때문입니다.
cell의 속성을 초기화시켜주지 않고 이를 활용해 재사용하기 때문에 이렇게 사진의 잔상이 남게되는 것 입니다.
이를 해결하기 위해서는 prepareForReuse()
메서드를 활용해야 합니다.
UICollectionViewCell
은 UICollectionReusableView
클래스를 상속받아 prepareForReuse()
를 사용할 수 있고, 이 메소드를 재정의하여 셀 재사용 시 적절한 처리를 해줄 수 있습니다.
해당 메서드를 활용하면 dequeue
메서드가 호출되기 전에 실행이 되어서 보여주고자 하는 view의 속성을 기본값으로 리셋시켜주기 때문에 뷰를 재사용될 수 있게 준비시켜준다고 합니다.
그런데 해당 메서드를 사용할 때 주의할 점은 이 메서드를 활용하여 새로운 데이터를 view에 할당하면 안된다는 것입니다. 새로운 데이터를 할당하는 것은 datasource 오브젝트의 책임이기 때문이죠~~
extension OpenMarketListCollectionViewCell {
override func prepareForReuse() {
super.prepareForReuse()
self.itemThumbnail.image = UIImage(named: "loadingPic")
self.itemTitleLabel.text = nil
self.itemPriceLabel.text = nil
self.itemStockLabel.text = nil
self.itemDiscountedPriceLabel.text = nil
}
}
extension OpenMarketGridCollectionViewCell {
override func prepareForReuse() {
super.prepareForReuse()
self.itemThumbnail.image = UIImage(named: "loadingPic")
self.itemTitleLabel.text = nil
self.itemPriceLabel.text = nil
self.itemStockLabel.text = nil
self.itemDiscountedPriceLabel.text = nil
}
}
해당 메서드를 cell의 extension에 구현하였습니다. reload()를 통해서 cell이 초기화 된 후 다시 dequeue 될 때 위에 선언한 메서드가 불려질 것이고 prepareForReuse
메서드를 통해서 로딩이미지가 잠시동안 보여지도록 설정하였습니다.
UITableViewCell/ UICollectionReusableView의 재사용