ios – Threading Subject in UICollectionViewCell having Photographs

[ad_1]

I’ve a UICollectionViewCell subclass which accommodates easy UIImageView subclass and UILabel subclass.

My subject is when collectioView is scrolled quick the cells are exhibiting completely different photographs than the one which they’re supposed to indicate. I do know it’s because the cells are reused and when new cells are proven they’re principally the previous cells which went out of view coz of scrolling. And completely different photographs are proven trigger every cell could fetches a number of photographs from the a number of urls coz of reusing .

repair this threading subject?

Issues I’ve tried,

  1. I’ve lastDownloadedImageUrl which preserve monitor of final url {that a} cell used to fetch the picture and whereas setting the picture to imageView in cell I examine whether or not the url String is identical lastDownloadedImageUr if not then I will not set the picture.

My mannequin for cell encompass array of struct referred to as ListModel which has identify and imgUrl

struct ListModel : Hashable{
    let identify : String
    let imgUrl : String?
}

In my ViewController I’ve assortment view added as subview and I am utilizing UICollectionViewDiffableDataSource. Right here is my code for assortment view cell configuration

    personal func configureDataSource(){
    guard let collectionView = collectionView else {return}
    dataSource = UICollectionViewDiffableDataSource<Part,ListModel>(collectionView: collectionView, cellProvider: { collectionView, indexPath, listModel in
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CLCatBreedListCell.reuseId, for: indexPath) as! CLCatBreedListCell
        cell.set(mannequin: listModel)
        return cell
    })
}

My CLCatBreedListCell ,

protocol ImageDownloadingProtocol : AnyObject {
    func shouldSetDownloadedImage(forUrl urlStr: String) -> Bool
}

class CLCatBreedListCell : UICollectionViewCell{
    
    static let reuseId = "CatbreedListCell"
    
    let catImageView : CLImageView = ViewFactory.getCLImageView()
    let catBreedNameLabel = CLTitleLabel(txtAlignment: .heart, fontSize: 14)
    
    var lastDownloadedImageUrl : String = ""
    
    override init(body: CGRect) {
        tremendous.init(body: body)
        configure()
    }
    
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been applied")
    }
    
    
    personal func configure(){
        addSubview(catImageView)
        addSubview(catBreedNameLabel)
        catImageView.delegate = self
        
        let padding: CGFloat = 5
        
        NSLayoutConstraint.activate([
            catImageView.leadingAnchor.constraint(greaterThanOrEqualTo: leadingAnchor,constant: padding),
            catImageView.trailingAnchor.constraint(lessThanOrEqualTo: trailingAnchor,constant: -padding),
            catImageView.topAnchor.constraint(equalTo: topAnchor,constant: padding),
            catImageView.heightAnchor.constraint(equalToConstant: 100),
            catImageView.widthAnchor.constraint(equalToConstant: 100),
            
            catBreedNameLabel.topAnchor.constraint(equalTo: catImageView.bottomAnchor, constant: padding),
            catBreedNameLabel.leadingAnchor.constraint(equalTo: leadingAnchor,constant: padding),
            catBreedNameLabel.trailingAnchor.constraint(equalTo: trailingAnchor,constant: -padding),
            catBreedNameLabel.heightAnchor.constraint(equalToConstant: 20)
        ])
    }
    
    
    func set(mannequin : ListModel){
        catBreedNameLabel.textual content = mannequin.identify
        lastDownloadedImageUrl = mannequin.imgUrl ?? ""
        if let imgURL = mannequin.imgUrl {
            catImageView.downloadImageFrom(urlStr: imgURL)
        }else {            
            catImageView.configureForFailedImageDowload()
        }
    }
}


extension CLCatBreedListCell : ImageDownloadingProtocol{
    
    func shouldSetDownloadedImage(forUrl urlStr: String) -> Bool {
        if lastDownloadedImageUrl == urlStr{
            return true
        }else {
            return false
        }
    }
}

I obtain photographs in my CLImageView utilizing the beneath code and pictures are cached contained in the RequestManager

 func downloadImageFrom(urlStr: String) {
    Process{
        do{
            let information = attempt await requestManager.downloadImage(from: urlStr)
            guard let downloadedImage = UIImage(information: information) else {
                DispatchQueue.fundamental.async {
                    self.activityIndicator.stopAnimating()
                    self.picture = self.placeHolderImage
                    self.contentMode = .scaleAspectFit
                }
                return
            }
            
            DispatchQueue.fundamental.async {
                guard let delegate = self.delegate else {return}
                if delegate.shouldSetDownloadedImage(forUrl: urlStr) {
                    self.configure(catImage: downloadedImage)
                    
                    self.activityIndicator.stopAnimating()
                    self.picture = downloadedImage
                    self.contentMode = .scaleToFill
                }
            }
        }catch{
            self.configureForFailedImageDowload()
        }
    }
}

I’d respect any assist .

[ad_2]

Leave a Reply

Your email address will not be published. Required fields are marked *