I have simple UICollectionViewCell that contains one product. My product have image(UIImageView), name(UILabel), description(UILabel), price(UILabel), rating(UIStackView) shown with 0 to 5 stars and buy button.
I fetch my products from JSON and save it to Array of products.
After app launch my UICollectionView populate with no problems. I use:
var product: Product? {
didSet {
populateProduct()
}
}
to populate data in Cell..
private func populateProduct() {
guard let product = product else { return }
let viewModel = ProductViewModel(product: product)
productImageView.loadImage(image: product.imageString)
productBrand.text = product.brand
productName.text = product.name
productDescription.text = product.description
productPrice.text = viewModel.price
if productRating.arrangedSubviews.count != 5 { // Check if there is rating already
for star in 1...5 {
let stars = product.score
if stars != 0 { // Doesn't show rating if there is none
var starImage = UIImageView(image: UIImage(named: "star-pink"))
if star > stars {
starImage = UIImageView(image: UIImage(named: "star-grey"))
}
starImage.contentMode = .scaleAspectFit
productRating.addArrangedSubview(starImage)
}
}
}
}
Problem is when I scroll collection view and some of my cells are dequed and reused. It doesn't happen every time, but often happens, that my cells swaps a data of products. Specifically the rating and the picture - so for example my first product have his own data, but rating of second product.
I think I fixed the image problem by this code in Cell:
override func prepareForReuse() {
super.prepareForReuse()
productImageView.image = nil
}
But I don't found how to reload arrangedSubviews
in rating StackView or reload whole UIStackView same as just image in UIImageView. Or is there another solution to avoid it?
CellForItemAt
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! ProductCell
cell.product = products[indexPath.row]
return cell
}
And why cells swaps just ratingView?