swift iOS - UICollectionView images mixed up after fast scroll

前端 未结 2 1757
闹比i
闹比i 2021-01-11 18:24

I am new to swift and iOS programming, but I have been able to build a mostly stable starting interface for my application in Xcode. The CollectionView grabs an image and te

相关标签:
2条回答
  • 2021-01-11 18:56

    You need to understand how dequeue works properly. There are very good articles for this.

    To summarise:

    To maintain scrolling smoothness, dequeue is used which essentially reuses cells after a certain limit. Say you have 10 visible cells at a time, it will likely create 16-18 (3-4 above, 3-4 below, just rough estimates) cells only, even though you might need 1000 cells.

    Now when you are doing this-

    let cell: SeriesCollectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! SeriesCollectionViewCell
    

    You are reusing an existing cell from already made cells. That's why you see old image for some time and then you see new image once it's loaded.

    You need to clear the old image as soon as you dequeue the cell.

    cell.seriesImage.image = UIImage()    //nil
    

    You will essentially set a blank placeholder this way in the image and not mess with imageCache being nil in your case.

    That solves this problem-

    Noticeably, if you do a slow or medium scroll, a different image will show before the correct image is rendered into the correct cell (the label text for the cells are always correct, only the image is ever off).

    Now when assigning the image for current cell, you need to check again, if the image you're assigning belongs to this cell or not. You need to check this because the image view you're assigning it to is being reused and it might be associated to a cell at an indexPath different from that of when the image load request was generated.

    When you a dequeue the cell and set the image property to nil, ask the seriesImage to remember the current indexPath for you.

    cell.seriesImage.indexPath = indexPath
    

    Later, you only assign the image to it, if the imageView still belongs to previously assigned indexPath. This works 100% with cell reuse.

    if cell.seriesImage.indexPath == indexPath
    cell.seriesImage.image = image
    

    You might need to consider setting the indexPath on UIImageView instance. Here's something I prepared and use for a similar scenario- UIView-Additions

    It is available in both Objective-C & Swift.

    0 讨论(0)
  • 2021-01-11 19:12

    Implement func prepareForReuse() in your custom cell class. And reset your image in prepareForReuse() function. so it will reset the image view before reuse the cell.

    0 讨论(0)
提交回复
热议问题