La Win Ko
La Win Ko

Reputation: 304

First cell and last cell are changing each other in UICollectionView

I have MenuItemCollectionView and FoodItemColletionView and I am setting FoodItemCollectionView in MenuItemColletionViewCell.Error happened in first MenuItemCell and last MenuItemCell are changing each other.But sometimes they are appeared right place.I have no idea to fix this error

This is MenuItemCollectionView

func numberOfSections(in collectionView: UICollectionView) -> Int {
    print("Food Array Count = \(self.foodArray.count)")
    return self.foodArray.count
}

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


func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {

    switch kind {
    case UICollectionElementKindSectionHeader:
        let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: RESUABLE_VIEW, for: indexPath) as! CollectionReusableView
        headerView.header.text = nameArray[indexPath.section]
        return headerView
    default:
        assert(false, "Unexpected element kind")
    }

}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    let width = UIScreen.main.bounds.width
    let height = UIScreen.main.bounds.height/3
    return CGSize(width: width, height: height)
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: ITEM_CELL, for: indexPath) as! MenuItemCollectionViewCell
    cell.foodArray.removeAll()
    cell.foodArray = self.foodArray[nameArray[indexPath.section]]!
    print("Cell COol index = \(indexPath.section) , ARrray count = \(cell.foodArray.count)")
    return cell
}

This is MenuItemCollectionViewCell and I set up FoodItemColletionView in this

import UIKit
import SDWebImage


class MenuItemCollectionViewCell: UICollectionViewCell ,UICollectionViewDelegate,UICollectionViewDataSource{

    @IBOutlet weak var foodItemColletion: UICollectionView!
    var foodArray :[Food] = []
    var imageArray : [UIImage?] = []
    let FOOD_ITEM_CELL : String = "FoodCell"

    override func awakeFromNib() {
        foodItemColletion.delegate = self
        foodItemColletion.dataSource = self
        super.awakeFromNib()
    }

    override func prepareForReuse() {
        foodArray.removeAll()
        super.prepareForReuse()
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        for food in foodArray{
            print("Title Menu item \(food.title)")
        }
        return foodArray.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: FOOD_ITEM_CELL, for: indexPath) as! FoodItemCollectionViewCell
        let foodObj = foodArray[indexPath.row]
        cell.foodLabel.text = foodObj.title
        cell.foodPrice.text = foodObj.price
        cell.foodImage.sd_setImage(with: URL(string: "\(URLS.IMG_URL)\(foodObj.imageUrl)"), placeholderImage: nil, options: .refreshCached, progress: nil, completed: nil)
        print("Title Menu Item Cell \(indexPath.item) = \(foodObj.title)")
        return cell
    }


}

This is FoodItemColletionViewCell

import UIKit

class FoodItemCollectionViewCell: UICollectionViewCell {
    @IBOutlet weak var foodImage: UIImageView!
    @IBOutlet weak var foodLabel: UILabel!
    @IBOutlet weak var foodPrice: UILabel!
    @IBOutlet weak var cardView: CardView!

    override func awakeFromNib() {
        foodImage.layer.masksToBounds = true
        foodImage.roundCorners(corners: [.topLeft,.topRight], radius: 5)
        cardView.setElevation(points: 1.5)
        layer.shouldRasterize = true
        layer.rasterizationScale = UIScreen.main.scale
        cardView.layer.cornerRadius = 5
    }

    override func prepareForReuse() {
        super.prepareForReuse()
        foodImage.image = nil
    }

}

extension UIImageView{
    func roundCorners(corners:UIRectCorner, radius: CGFloat) {
        let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
        let mask = CAShapeLayer()
        mask.path = path.cgPath
        self.layer.mask = mask
    }
}

This is top screen that is actually what I want

This is bottom screen that is actually want I want too

But when i scroll fast again from top to bottom, first cell moved to last cell and last cell moved to first cell.This is what happened what i want to fix

Upvotes: 0

Views: 950

Answers (1)

Milan Nosáľ
Milan Nosáľ

Reputation: 19737

In MenuItemCollectionView change this method:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: ITEM_CELL, for: indexPath) as! MenuItemCollectionViewCell
    cell.foodArray.removeAll()
    cell.foodArray = self.foodArray[nameArray[indexPath.section]]!

    // add this, or else because of reusing the old data will be presented, even though you have set the new one
    cell.foodItemColletion.reloadData()

    print("Cell COol index = \(indexPath.section) , ARrray count = \(cell.foodArray.count)")
    return cell
}

Upvotes: 1

Related Questions