ios 下载后UICollectionView不会显示图像-情节提要

unftdfkk  于 2023-03-24  发布在  iOS
关注(0)|答案(2)|浏览(204)

我有一个DetailViewController,当你点击一个表格视图单元格时,它会被连接到,详细视图会显示一个标签,评级和一个collectionView,UICollectionView的设置是这样的,理想情况下,它应该显示两个下载并放入图像数组的图像

class DetailViewController: UIViewController , UICollectionViewDelegate , UICollectionViewDataSource{

    @IBOutlet weak var collectionView: UICollectionView!
    
    @IBOutlet weak var LabelView: UILabel!
    
    @IBOutlet weak var RatingsView: CosmosView!
    
    var mv : Result?
    
    var imgArr = [UIImage]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        
        LabelView.text = mv?.title
        RatingsView.rating = Double((mv!.vote_average / 2))
        
        let uri = "https://image.tmdb.org/t/p/w92" + mv!.poster_path
        downloadImage(with : uri){image in
            guard let image  = image else { return}
            self.imgArr.append(image)
        }

        let bUri = "https://image.tmdb.org/t/p/w92" + mv!.backdrop_path
        downloadImage(with : bUri){image in
            guard let image  = image else { return}
            self.imgArr.append(image)
            dump(self.imgArr)
        }
        
    }
    
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return imgArr.count
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath) as! CollectionViewCell
        cell.imgImage.image = imgArr[indexPath.row]
        return cell
    }
    
    func downloadImage(with urlString : String , imageCompletionHandler: @escaping (UIImage?) -> Void){
            guard let url = URL.init(string: urlString) else {
                return  imageCompletionHandler(nil)
            }
            let resource = ImageResource(downloadURL: url)
            
            KingfisherManager.shared.retrieveImage(with: resource, options: nil, progressBlock: nil) { result in
                switch result {
                case .success(let value):
                    imageCompletionHandler(value.image)
                case .failure:
                    imageCompletionHandler(nil)
                }
            }
        }

}

下面是它在故事板中的样子,我已经分配了适当的类和重用标识符

但我看不到任何图像由于某种原因

我不知道为什么它不显示图像,在我改变布局以添加主堆栈视图之前,它确实显示了,但我不知道为什么一个小的布局变化会影响,我仍然认为我在代码中做错了什么。我尝试添加.reloadData()和其他故障排除,但它不起作用。图像正在下载,如在输出转储中看到的,当您转到详细视图时会打印出来。

请帮帮我。先谢谢你

iyfjxgzm

iyfjxgzm1#

您应该始终在主线程上更新UI上的任何内容。请将返回的图像添加到DispatchQueue.main.async {}中

y53ybaqx

y53ybaqx2#

几乎可以肯定--问题是集合视图在下载*图像之前加载***。
viewDidLoad()中,你启动了一个异步下载两张图片的过程。这将需要“一些时间”--可能需要1/4秒,1/2秒......或者它可能非常快(如果它们是小图片),只需要1/10秒。
但是,numberOfItemsInSection可能在
1/100秒**时被调用--远远早于图像下载。
将其更改为:

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

    print("number of images:", imgArr.count)
    return imgArr.count

}

您可能会看到number of images: 0作为输出。
在完成块中,您需要添加:

DispatchQueue.main.async {
    self.collectionView.reloadData()
}

另外请注意......这两个图像不一定会连续下载。如果您需要按该顺序下载,您可以:

  • 下载第一映像,然后在其完成块中开始下载第二映像,或者
  • imgArr中的两个“占位符”图像开始,然后按所需顺序替换它们

在任何情况下,您仍然需要在 * 下载完映像后 * 调用.reloadData()

相关问题