ios - CollectionCell 显示错误的图像?

标签 ios swift uitableview uicollectionview

我有一个包含单元格的 TableView,一个单元格包含一个 CollectionView

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

如果我在 CollectionView 可见 时向数据源添加新元素,则它可以正常工作。

但是如果我在 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
    }
}

照片单元格:

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 }
    }
}

我做错了什么?我确实正确地更新了数据源,我确实在 Collection View 上执行批量更新以插入正确的单元格..

Updated details:

主视图 Controller :

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)
    }
}

最佳答案

首先在cellForRowAt

cell.photosCollectionView.reloadData()
return cell

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

关于ios - CollectionCell 显示错误的图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51324290/

相关文章:

ios - Delphi4 XE/iOS/读取XML文件/

ios - 基于 USER_INTERFACE_IDIOM 运行 Objective C

ios - 我制作了表格 View ,即使在应用程序关闭后如何保存项目?

ios - iPhone 和 Apple Watch 之间的 WatchConnectivity 超时错误

ios - Urbanairship 代表不工作

ios - 在 crashlytics swift/ios 中具有非常大的行号值的 EXC_BREAKPOINT

ios - 使用 AudioKit 锁定屏幕中的音频控件

ios - 如何获得默认的单元格分隔符颜色?另外,如何设置每个单元格的分隔符颜色?

ios - 如何从Objective c中的MKMapKit中删除 map 位置和注释

ios - 来自 ViewController 外部的 Alamofire 请求