swift - 如何从 firebase-storage 下载图像以显示在 collectionViewCell 的 Imageview(Swift)中
问题描述
我已将图像上传到 firebase-storage 并将 downloadURL 保存到数据库内的键/值对中。我编写了一个代码,假设在检索到数据后,如果 url 有效,它将在 collectionView 中显示图像。代码在 cellForItemAt 执行,因为包含图片的 collectionView 嵌入在另一个 collectionView 中(将被称为 Main 或 MainCV 以防止混淆)。
为了解决这个问题,我尝试在 MainCV 中重新加载集合视图的数据,并尝试仅使用 ImageView 测试视图控制器上的代码(不成功)。
// function to display images
private func icon(_ imageURL: String) -> UIImage {
//print("imageURL is \(imageURL)")
let url = URL(string: imageURL)
var image: UIImage?
var imageData:Data?
if url == nil {
print("URL is \(imageURL)")
return #imageLiteral(resourceName: "ic_person_outline_white_2x")
} else {
URLSession.shared.dataTask(with: url!) { (data, response, error) in
if error != nil {
print("error")
return
}
DispatchQueue.main.async {
imageData = data
image = UIImage(data: imageData!)
}
}.resume()
return image ?? #imageLiteral(resourceName: "ic_person_outline_white_2x")
}
}
CellForItemAt 代码块
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! ImageCell
let imageOption = self.imageData[indexPath.row]
cell.iconImageView.image = icon(imageOption)
return cell
//imageData is an array with empty values that is populated with database values and subsequently reloaded
}
正如我之前所说,预期的结果是在 collectionView 内显示来自 firebaseStorage 的图像。我的代码不会呈现任何错误,但总是返回默认图像以及打印我确认为我要显示的图像的准确 http 的 imageURl。
解决方案
你需要学习一些关于异步编程的知识。
您的函数会立即返回,但URLSession.shared.dataTask(with: url!)
需要一些时间。时间线:
- 图像 = 无
- 开始获取数据
- 回图??默认图片
- 获取数据完成(函数返回后 -> 图像数据丢失)
与其立即返回,不如在函数中提供将图像作为参数的闭包:
private func icon(_ imageURL: String, closure: (UIImage) -> Void)
并将您的代码更新为
URLSession.shared.dataTask(with: url!) { (data, response, error) in
if error != nil {
print("error")
closure(#imageLiteral(resourceName: "ic_person_outline_white_2x"))
}
DispatchQueue.main.async {
imageData = data
image = UIImage(data: imageData!)
closure(image)
}
}.resume()
闭包本身可以是一个接受图像作为参数并将此图像异步设置到您的集合视图单元格的函数
此外,您希望在加载图像之前提供一些默认或加载图像。或者使用 ActivityIndicator。
希望这可以帮助!
推荐阅读
- java - 如何通过将其中一个值切换为键来创建 HashMap 的 HashMap
- html5-canvas - KonjaJs 使用 toDataUrl 保存背景图像
- r - 有没有办法过滤数据框以将与另一个数据框中的值匹配的值保留?
- java - How to Deserialize unknown primitive json property type using Gson
- batch-file - 有没有办法用批处理启动命令提示符,然后在该命令窗口中运行多个命令?
- java - 在读取 txt 文件时从 1D 数组制作 2D 数组
- vba - 将附件字段文件路径提取到不同的列
- macos - macOS SwiftUI 关闭通过菜单中的 segue 呈现的应用模式 NSHostingController?
- react-native - React-Native Navigation v5:如何更改 tabBarLabel 或 tabBarIcon 以及特定屏幕上选项卡的颜色背景?
- kubernetes - KubernetesPodOperator 无法识别 service_account_name