Search code examples
swiftuicollectionviewuicollectionviewcellactivity-indicator

How to show activity indicator in UICollectionView cell?


I'm trying to show activity indicator for every cell until the image for UICollectionView cell show up, but it only shown in the last cell.

view

My code:

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

    cell.backgroundColor = .blue
    let containerView = UIView(frame: CGRect(x: 0, y: 0, width: 160, height: 200))
    let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 160, height: 200))

    cell.contentView.addSubview(activityIndicator)
    activityIndicator.startAnimating()

    containerView.backgroundColor = .magenta

    containerView.addSubview(imageView)

    guard imageArray.count == tempListLength && tempListLength > 0 else {
        DispatchQueue.main.async {
            self.activityIndicator.center = cell.contentView.center
        }
        return cell
    }

    DispatchQueue.main.async {
        self.activityIndicator.stopAnimating()
    }
    imageView.image = imageArray[indexPath.row]

    cell.contentView.addSubview(imageView)

    return cell
}

Solution

  • Add Activity indicator in your custom cell

    class CustomCell: UICollectionViewCell {
    
      private lazy var spinner = UIActivityIndicatorView(style: .large)
    
            override init(frame: CGRect) {
                super.init(frame: frame)
                commonInit()
            }
    
            required init?(coder: NSCoder) {
                super.init(coder: coder)
                commonInit()
            }
    
            private func commonInit() {
                 spinner.translatesAutoresizingMaskIntoConstraints = false
                contentView.addSubview(spinner)
    
                spinner.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
                spinner.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
             }
        }
    

    Then in cellForItemAt method you just need to do is to start animate and stop animate

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
      let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CustomCell", for: indexPath)
    
       cell.spinner.startAnimating() 
    // OR
      cell.spinner.stopAnimating()
    
    }