Nolan Ranolin
Nolan Ranolin

Reputation: 409

CollectionView loading slowly

My collectionView gets it's data from Firebase. Theres a firebase variable to set the number of cells and to get download links for the cell images which are downloaded using SDWebImage. The images that it downloads for each cell are around 60 kilobytes but the collectionview takes around 5 seconds to load. Also when it does load it shows all the cell images as the 1st cell image then changes to the correct image a second later.

im using swift 3

Here's my code

    override func viewDidLoad() {
            super.viewDidLoad()

        //firebase 
        FIRDatabase.database().reference(withPath: "Radio").child("numCells").observeSingleEvent(of: .value, with: { (snapshot) in

            if let snapInt = snapshot.value as? Int {

                self.numCells = snapInt

                self.collectionView?.performBatchUpdates(
                    {
                        self.collectionView?.reloadSections(NSIndexSet(index: 0) as IndexSet)
                }, completion: { (finished:Bool) -> Void in
                })


            }

        }) { (error) in
            print(error.localizedDescription)
        }
    }





    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
            // #warning Incomplete implementation, return the number of items
            return numCells
        }




 override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath)

                let icon = cell.viewWithTag(3) as! UIImageView


        //Firebase
        FIRDatabase.database().reference(withPath: "Icons").child("img\(indexPath.row)").child("imgLink").observeSingleEvent(of: .value, with: { (snapshot) in

            if let snapString = snapshot.value as? String {

                icon.sd_setShowActivityIndicatorView(true)
                icon.sd_setIndicatorStyle(.gray)
                icon.sd_setImage(with: URL(string: snapString))
            }

        }) { (error) in
            print(error.localizedDescription)
        }//firebase end



        return cell
    }

Upvotes: 1

Views: 958

Answers (1)

Vasilii Muravev
Vasilii Muravev

Reputation: 3163

Do not use cellForItemAtIndexPath for heavy requests:

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    return collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath)
}

func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
    FIRDatabase.database().reference(withPath: "Icons").child("img\(indexPath.row)").child("imgLink").observeSingleEvent(of: .value, with: { [weak collectionView] (snapshot) in
        guard let collectionView = collectionView else { return }
        let cell = collectionView.cellForItem(at: indexPath)
        /* do whatever you need with cell */
    }) { (error) in
        /* handle error */
    }
}

Upvotes: 1

Related Questions