我正在从Firebase获取用户图像。用户在数据库中最多可以上传6张图像。我想按正确的顺序(0-6)将图像下载到CollectionView中。
当我尝试使用CompletionHandler时,它并没有按我希望的那样工作。 CollectionView的重新加载在获取图像之前很久就完成了,没有图像显示,因为在调用reloadData之后将图像放入数组中。
非常感谢您提供有关此问题的帮助。
这是我的代码:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
downloadAndReload()
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return arrayImages.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "swipeCell", for: indexPath as IndexPath) as! ProfileCardCollectionViewCell
let image = self.arrayImages[indexPath.item]
cell.swipeProfileImage.image = image
print("lägger ut cell")
return cell
}
func downloadAndReload(){
cachedImage(completion: { message in
print(message)
self.swipeCollectionView.reloadData()
})
}
func cachedImage(completion: @escaping (_ message: String) -> Void){
if let uid = Auth.auth().currentUser?.uid{
for i in 0...6{
let url = URL(string: uid+String(i))
SDWebImageManager.shared.loadImage(with: url, options: .refreshCached, progress: .none ,completed: { (image, data, error, _, _, _) in
if let error = error{
print("Couldn't download image")
self.downloadImage(i: i, completion: {_ in
})
}
else{
print("Could download image")
self.arrayImages.append(image!)
}
})
}
completion("DONE")
}
}
func downloadImage(i: Int, completion: @escaping (_ fetchWorked: String) -> Void){
print("Downloading Image")
let g = DispatchGroup()
g.enter()
if let uid = Auth.auth().currentUser?.uid{
let imagesStorageRef = Storage.storage().reference().child("profilepic/").child(uid+String(i))
imagesStorageRef.downloadURL { url, error in
guard let url = url else { return }
SDWebImageManager.shared.loadImage(with: url, options: .refreshCached, progress: .none ,completed: { (image, data, error, _, _, _) in
if let error = error{
}
else{
self.arrayImages.append(image!)
}
})
g.leave()
}
g.notify(queue: .main, execute: {
completion("Done")
})
}
}
答案 0 :(得分:0)
问题是您有嵌套的闭包,因此在调用时:
SDWebImageManager.shared.loadImage(with: url, options: .refreshCached, progress: .none ,completed: { (image, data, error, _, _, _) in
if let error = error{
print("Couldn't download image")
self.downloadImage(i: i, completion: {_ in
})
else{
print("Could download image")
self.arrayImages.append(image!)
}
})
其中的所有内容都只会在“ loadImage”完成时被调用,因此您的“ for”将调用“ SDWebImageManager.shared.loadImage” 6次,然后再调用“ completion(“ Done”)”。
因此,您的代码在完成图像处理之前将调用“ completion(“ Done”)“,因此在没有图像或可能有一对图像的情况下重新加载数据。
您需要等待提取完成后再调用reloadData(),这取决于您的需要,但是您可以根据需要提取图像,将图像设置为单元格内容时,调用提取图像(首先从缓存中获取图像,如果不可用则下载),然后仅更新图像的显示位置。 这样,您的应用程序将更动态地显示在屏幕上,还可以设置占位符图像。