【问题标题】:UICollectionview not fully loaded image from CoreData get randomly blank cell imageUICollectionview 未从 CoreData 完全加载图像获取随机空白单元格图像
【发布时间】:2024-01-19 00:38:01
【问题描述】:

嗨,我目前在 iOS 10 + Swift 3 上遇到了 UICollectionView 的问题。一旦我的视图加载了每个单元格中的 ImageView,就会随机变为空白,其中一些可以加载。

Here is my random output

现在我必须在重新加载 CollectionView 的数据之前延迟,但它仍然不能 100% 解决我的问题,有时我的单元格仍然是空白的。

视图控制器

@IBOutlet weak var petCollection: UICollectionView!
var petObj: [Pet] = []

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return self.petObj.count
}

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

    let nsDocumentDirectory = FileManager.SearchPathDirectory.documentDirectory
    let nsUserDomainMask    = FileManager.SearchPathDomainMask.userDomainMask
    let paths               = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true)

    let dirPath          = paths.first!
    let imageURL = URL(fileURLWithPath: dirPath).appendingPathComponent(petObj[indexPath.item].petImage!)
    let image    = UIImage(contentsOfFile: imageURL.path)

    cell.collectionViewImage.image = image

    return cell
}

override func viewDidLoad() {
    super.viewDidLoad()
    self.petCollection.delegate = self
    self.petCollection.dataSource = self
}
override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
        petCollection.reloadData()
    }
}

UICollectionViewCell

class PetCollectionViewCell: UICollectionViewCell {
    @IBOutlet weak var collectionViewImage: UIImageView!
}

我假设是在 UICollectionView 完成创建单元格之前调用了 reloadData。

我使用CoreData存储文件路径,所有图像都保存在文档目录中。

【问题讨论】:

    标签: ios swift uicollectionview


    【解决方案1】:

    是的,您的集合视图将在调用 viewDidLoad 时加载其数据,这就是您的用户进入此视图控制器的时候。

    您应该使用这个库,而不是使用延迟来异步重新加载数据:

    https://github.com/rs/SDWebImage

    它将处理图像的异步加载。

    你可以像这样使用这个库:

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath as IndexPath) as! PetCollectionViewCell
    
        let nsDocumentDirectory = FileManager.SearchPathDirectory.documentDirectory
        let nsUserDomainMask    = FileManager.SearchPathDomainMask.userDomainMask
        let paths               = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true)
    
    
        cell.collectionViewImage.sd_setImage(with: URL(string: "yourPathToImage"), placeholderImage: UIImage(named: "placeholder.png"))
    
        return cell
    }
    

    【讨论】:

    • 该库可以与本地图像文件一起使用吗?因为我使用CoreData来存储保存在文档目录中的图片路径。
    • 是的,您也可以使用本地图像。看看这个:*.com/questions/37970124/…
    • 在我尝试了上面的代码后,问题仍然存在ibb.co/kxhaKQ如果你看到图像它只加载了 3 三张图片,其他的仍然是占位符图像(人类图标)我必须在某个地方重新加载数据吗?跨度>
    • 我发现一个奇怪的问题,如果我将文件名替换成这样 appendingPathComponent("myimage.png") 图像正确显示没有任何问题但是如果我从 CoreData 获取的结果更改为文件名,如 appendingPathComponent( result.imageName) 和 if let image = UIImage(contentsOfFile: imageURL.path) 总是返回 false 好像是 Coredata 还没有加载完成的问题?