CollectionCell显示错误的图像?

时间:2018-07-13 11:39:19

标签: ios swift uitableview uicollectionview

我有一个带有单元格的TableView,并且一个单元格中有一个CollectionView

在CollectionView中,我的单元格带有UIImageViews。

如果我在CollectionView is visible期间向数据源添加新元素,那么它将正常工作。

但是如果我在TableView中向下滚动,请添加新元素然后向上滚动,即使添加了新单元格,它们也会显示错误的图像。

视频:https://youtu.be/QwvMv2xaaAI


代码:

MainViewController (不是全部)

func addNewPhotos(newPhotosArray: [Photo]){
    var collectionViewInserts : [IndexPath] = []
    for (i in 0...newPhotosArray.count) {

        // I add the new photos to the datasource
        PhotosStore.shared.photos.insert(newPhotosArray[i], at: 0)
        // Then save the indexPath what needs to be inserted
        collectionViewInserts.insert(IndexPath(row: i, section: 0), at: 0)
    }

    if let cell = self.tableView.cellForRow(at: IndexPath(row: 0, section: 0)) as? PhotosCell {
        cell.photosCollectionView.performBatchUpdates({
            cell.photosCollectionView.insertItems(at: collectionViewInserts)
        }, completion: nil)
    }
}

extension MainViewController: UICollectionViewDelegate, UICollectionViewDataSource {

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return PhotosStore.shared.photos.count
    }

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

        cell.photoImageView.downloadedFrom(link: (appSettings.url + "/resources/img/wp/prev/" + PhotosStore.shared.photos[indexPath.item].fileName))

        return cell
    }
}

PhotosCell:

import UIKit

class PhotosCell : UITableViewCell{

    @IBOutlet weak var photosCollectionView : UICollectionView!

}

extension PhotosCell {

    func setCollectionViewDataSourceDelegate<D: UICollectionViewDataSource & UICollectionViewDelegate>(_ dataSourceDelegate: D, forRow row: Int) {

        // IF I PLACE A .reloadData() HERE, THEN IT WORKS BUT THEN THE CELL FLICKERS/JUMPS WHEN APPEARING ON SCREEN

        let itemSize = 70

        photosCollectionView.delegate = dataSourceDelegate
        photosCollectionView.dataSource = dataSourceDelegate

        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = UICollectionViewScrollDirection.horizontal
        layout.minimumInteritemSpacing = 0
        layout.minimumLineSpacing = 0
        layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
        layout.itemSize = CGSize(width: itemSize, height: itemSize)
        photosCollectionView.setCollectionViewLayout(layout, animated: true)

        photosCollectionView.tag = row
        photosCollectionView.setContentOffset(photosCollectionView.contentOffset, animated:false) // Stops collection view if it was scrolling.
        photosCollectionView.reloadData()
    }

    var collectionViewOffset: CGFloat {
        set { photosCollectionView.contentOffset.x = newValue }
        get { return photosCollectionView.contentOffset.x }
    }
}

我怎么了?我确实正确更新了数据源,也确实对集合视图执行了批更新以插入正确的单元格。

  

更新的详细信息:

MainViewController:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        // Photos on top
        if indexPath.section == 0 {
            let cell = tableView.dequeueReusableCell(withIdentifier: "PhotosCell", for: indexPath) as! PhotosCell
            cell.setCollectionViewDataSourceDelegate(self, forRow: indexPath.row)
            cell.collectionViewOffset = storedPhotosCollectionViewOffset[indexPath.row] ?? 0
            return cell
        }
   ... other cells ...
}

下载图像的扩展名:(我相信这不是问题,只是为了以防万一)

extension UIImageView {
    func downloadedFrom(url: URL, contentMode mode: UIViewContentMode = .scaleAspectFit) {

        image = nil

        if let cachedImage = ImageCache.shared.loadCachedImage(url: url) {
            image = cachedImage
            return
        }

        contentMode = mode
        URLSession.shared.dataTask(with: url) { data, response, error in
            guard
                let httpURLResponse = response as? HTTPURLResponse, httpURLResponse.statusCode == 200,
                let mimeType = response?.mimeType, mimeType.hasPrefix("image"),
                let data = data, error == nil,
                let image = UIImage(data: data)
                else {
                    DispatchQueue.main.async {
                        self.image = UIImage(named: "imageMissing")
                    }
                    return
                }
                DispatchQueue.main.async {
                    self.image = image
                    ImageCache.shared.cacheImage(image: image, url: url)
                }
            }.resume()
    }
    func downloadedFrom(link: String, contentMode mode: UIViewContentMode = .scaleAspectFit) {
            guard let url = URL(string: link) else { return }
             return downloadedFrom(url: url, contentMode: mode)
    }
}

1 个答案:

答案 0 :(得分:1)

cellForRowAt中的第一名

cell.photosCollectionView.reloadData()
return cell

第二,您必须注意,每次滚动时都要下载图像(为imageView考虑一个虚拟图像或为其设置背景),因此请使用SDWebImage