Abhiram
Abhiram

Reputation: 247

Way to limit collection view number of cells loaded at a time

I have 200 items in the array and I am passing to the collection view While Running on the device it gets Crashed due to memory warning. Is there any way to limit cell to a row at index path according to scrolling.Due to downloading images it showing memory warning. if I skip the downloading part then it's not crashing.

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    var cell:ProductListCell? = collectionView.dequeueReusableCell(withReuseIdentifier: "ProductListCell", for: indexPath) as? ProductListCell

    if (cell == nil) {
        let nib: NSArray = Bundle.main.loadNibNamed("ProductListCell", owner: self, options: nil)! as NSArray
        cell = (nib.object(at: 0) as? ProductListCell)!
        cell?.layer.shouldRasterize = true
        cell?.layer.rasterizationScale = UIScreen.main.scale;
    }

        if let url = NSURL(string: ((self.objCategorywiseResponse.SimilirProductsList![indexPath.row].productPic)!)) {
            cell?.imgProduct.sd_setImage(with: url as URL, placeholderImage: UIImage(named: "placeholder.png"))
        }

    if let strProductName = self.objCategorywiseResponse.SimilirProductsList![indexPath.row].ProductName {
        cell?.lblProductName.text = strProductName
    }

    cell?.lblProductDesc .text = ""

    if let strProductPrice = self.objCategorywiseResponse.SimilirProductsList![indexPath.row].MRP {
        cell?.lblProductPrice.attributedText = Common().setPrice(Price:strProductPrice, StrikePrice1:(self.objCategorywiseResponse.SimilirProductsList![indexPath.row].discountprice)!)
    }

    if let strDiscount = self.objCategorywiseResponse.SimilirProductsList![indexPath.row].DiscountPercentage {
        if strDiscount > 0 {
            cell?.btnDiscount.setTitle("\(strDiscount)% off", for: .normal)
        } else {
            cell?.btnDiscount.isHidden = true
        }
    }

    if let strRatingDesc = self.objCategorywiseResponse.SimilirProductsList![indexPath.row].TotalRating_Reviews {
        cell?.lblRatingdesc.text = strRatingDesc
    }

    if let strRating = self.objCategorywiseResponse.SimilirProductsList![indexPath.row].AvgRatingCount {
        cell?.lblRating.text = "\(strRating)"
    }

    if let intRating = self.objCategorywiseResponse.SimilirProductsList![indexPath.row].AvgRatingCount {
        cell?.subViewRating.rating = intRating
    }

    if let strShopName = self.objCategorywiseResponse.SimilirProductsList![indexPath.row].ShopName {
        cell?.lblShopName.text = strShopName
    }

    if let strDisctance = self.objCategorywiseResponse.SimilirProductsList![indexPath.row].Distance {
        cell?.lblDistance.setTitle("\(strDisctance) km near by you", for: .normal)
    }

    if let strLandLineNo = self.objCategorywiseResponse.SimilirProductsList![indexPath.row].LandLineNumber {
        cell?.lblMobileNo.text = "\(strLandLineNo)"
    }

    cell?.btnAddToCompare.tag = indexPath.row
    cell?.btnAddToCompare.addTarget(self, action: #selector(btnClickedAddToCompare(_:)), for: .touchUpInside)

    cell?.btnAddProduct.tag = indexPath.row
    cell?.btnAddProduct.addTarget(self, action: #selector(btnClickedAddProduct(_:)), for: .touchUpInside)

    cell?.btnCall.tag = indexPath.row
     cell?.btnCall.addTarget(self, action: #selector(self.callCellactn(_:)), for: .touchUpInside)

    cell?.btnMap.tag = indexPath.row
     cell?.btnMap.addTarget(self, action: #selector(self.locationCellactn(_:)), for: .touchUpInside)

    return cell!
}

Upvotes: 3

Views: 1139

Answers (4)

Abhiram
Abhiram

Reputation: 247

I have placed Collection View in ScrollView Thats why it is calling All 100 cells at a time. then i removed Scroll view then it is working Fine

Upvotes: 0

Akhil
Akhil

Reputation: 170

You are not properly reusing the cell that is the reason for memory warning Remove this `

if (cell == nil) {
    let nib: NSArray = Bundle.main.loadNibNamed("ProductListCell", owner: self, options: nil)! as NSArray
    cell = (nib.object(at: 0) as? ProductListCell)!
}

` Use the below code in viewDidLoad

 self.collectionView.register(UINib.init(nibName: "ProductListCell", bundle: nil), forCellWithReuseIdentifier: "ProductListCell")

If the issue is still occuring use the below library for image caching Kingfisher

it is a lightweight library with less memory impact

Upvotes: 0

Clafou
Clafou

Reputation: 15400

I don't think the number of cells is the issue. UICollectionView manages the collection of cells automatically, including disposing of off-screen cells.

I think it's more likely that you are experiencing memory leaks that prevent the cells from being actually deallocated when UICollectionView lets go of them. You have a lot of blocks in there that may be causing such memory leaks.

Upvotes: 2

Jaydeep Vora
Jaydeep Vora

Reputation: 6213

You can use pagination concept to stop loading all the cell at a time. And it revoke the high memory usage of reusable cell.

check this link will elaborate to use of Pagination concept.

Upvotes: 1

Related Questions