我正在尝试在我的SwiftUI应用中使用PHCachingImageManager
加载照片。我可以获取照片,但无法获取SwiftUI视图来显示它。
我有一个称为PhotoCell
的视图,如下所示。我将Binding<UIImage>
传递给使用PHCachingImageManager
加载资产的函数。这可以起作用,并将90x120的图像返回到Binding
的设置功能。在设置功能内,您可以看到hasLoadedImage
设置为true
。
视图的body
由if
语句组成。除了第一次hasLoadedImage
的值为false
时,都不会执行此操作。我不知道该怎么办。正如测试一样,我将Image
内的if
替换为Text
,但即使hasLoadedImage
设置为true
,它也不会显示。我在if
getter中经常使用body
语句。
我觉得我已经忽略了显而易见的事情。
struct PhotoCell: View {
@State var photoImage: UIImage = UIImage()
@State var hasLoadedImage: Bool = false
var photoAsset: PHAsset
var photoBinding: Binding<UIImage> {
Binding<UIImage>(
get: {
return self.photoImage
},
set: {(newValue) in
print("Loaded image \(newValue.size)") // this prints with the correct size
self.photoImage = newValue
self.hasLoadedImage = true // seems to have no effect
})
}
init(photoAsset: PHAsset) {
self.photoAsset = photoAsset
let options: PHImageRequestOptions = PHImageRequestOptions()
options.deliveryMode = .fastFormat
options.isNetworkAccessAllowed = true
options.resizeMode = .fast
PhotosManager.shared.loadAsset(asset: photoAsset, size: CGSize(width: 48, height: 48), options: options, image: self.photoBinding)
}
var body: some View {
if self.hasLoadedImage { // shouldn't this execute once the value is changed??
return AnyView(
Image(uiImage: self.photoImage)
.resizable()
.frame(width: 48, height: 48)
)
} else {
return AnyView(
Image(systemName: "goforward")
)
}
}
}
因此,出于无奈,我想出了一种解决方法,它实际上比我想做的要简单。我为UIViewRepresentable
构建了UIImageView
包装器:
struct MyImage: UIViewRepresentable {
var photoAsset: PHAsset
func makeUIView(context: Context) -> UIImageView {
let uiView = UIImageView(image: UIImage(systemName: "goforward") ?? UIImage())
return uiView
}
func updateUIView(_ uiView: UIImageView, context: Context) {
let options: PHImageRequestOptions = PHImageRequestOptions()
options.deliveryMode = .fastFormat
options.isNetworkAccessAllowed = true
options.resizeMode = .fast
PhotosManager.shared.loadAsset(asset: photoAsset, into: uiView, options: options)
}
}
loadAsset
函数就是这样,如果要对其进行测试,其中imageManager
是PHCachingImageManager
的实例。我想了解为什么我发布的问题不起作用。我怀疑这与requestImage
中的闭包和不当捕获self
有关,但我只是看不到它。
func loadAsset(asset: PHAsset, into imageView: UIImageView, options: PHImageRequestOptions?) {
let size = CGSize(width: 48, height: 48)
imageManager.requestImage(for: asset, targetSize: size, contentMode: .aspectFit, options: options, resultHandler: { (result, info) in
if let result = result {
imageView.image = result
}
})
}