这是一个迟到的答案,但希望它会对其他人有所帮助。
是的,这是可能的。您可以使用PHPickerViewController 选择照片以获取具有assetIdentifier 属性的PHPickerResult。 assetIdentifier 持久且唯一地标识照片。当您要加载图像时,读取保存的assetIdentifier 并使用PHAsset.fetchAssets() 检索资产,然后使用PHImageManager.requestImage() 获取UIImage。这样,您需要在应用中存储的只是assetIdentifier,而不是图像数据。
这里是一些示例代码(适用于 iOS15),用于选择一张照片并获取 assetIdentifier:
import PhotosUI
import SwiftUI
struct PhotoPicker: UIViewControllerRepresentable {
@Environment(\.dismiss) var dismiss
@Binding var assetIdentifier: String?
typealias UIViewControllerType = PHPickerViewController
func makeUIViewController(context: Context) -> PHPickerViewController {
var configuration = PHPickerConfiguration(photoLibrary: PHPhotoLibrary.shared())
configuration.selectionLimit = 1
configuration.filter = .images
let picker = PHPickerViewController(configuration: configuration)
picker.delegate = context.coordinator
return picker
}
func updateUIViewController(_ uiViewController: PHPickerViewController, context: Context) {
// Do nothing.
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, UINavigationControllerDelegate, PHPickerViewControllerDelegate {
let parent: PhotoPicker
init(_ parent: PhotoPicker) {
self.parent = parent
}
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
parent.dismiss()
// Only 1 image can be selected, so ignore any additional elements.
guard let result = results.first else {
return
}
parent.assetIdentifier = result.assetIdentifier
}
}
}
要使用它:PhotoPicker(assetIdentifier: $assetIdentifier)
然后从assetIdentifier 检索图像使用:
import Photos
import SwiftUI
struct LoadedImageView: View {
@State var assetIdentifier: String
@State private var image: Image? = nil
var body: some View {
VStack {
if let image = image {
image
.resizable()
.aspectRatio(contentMode: .fit)
}
}
.onAppear(perform: loadImage)
}
func loadImage() {
let fetchResults: PHFetchResult<PHAsset> =
PHAsset.fetchAssets(withLocalIdentifiers: [assetIdentifier], options: nil)
guard let asset: PHAsset = fetchResults.firstObject else {
return
}
let manager = PHImageManager()
manager.requestImage(for: asset, targetSize: PHImageManagerMaximumSize,
contentMode: .aspectFit, options: nil) { (uiImage, _) in
if let uiImage = uiImage {
self.image = Image(uiImage: uiImage)
}
}
}
}