通过SwiftUI 的 PhotosPicker 视图 ,我们从用户照片库导入一张或多张照片。为了避免造成任何性能问题,数据以一种名为PhotosPickerItem 的特殊类型提供给我们,然后我们可以异步加载该类型,以将数据转换为 SwiftUI 图像。
单选
这总共需要五个步骤:
- 导入框架
import PhotosUI
import SwiftUI
2.其次,创建两个属性:一个用于存储所选项目,另一个用于将该项目存储为 SwiftUI 图像。
@State private var pickerItem: PhotosPickerItem?
@State private var selectedImage: Image?
这种区别很重要,因为在我们实际要求加载之前,所选项目只是对用户照片库中图片的引用。
3.在 SwiftUI 视图层次结构中的某个位置添加一个PhotosPicker 视图
VStack {
PhotosPicker("选择照片", selection: $pickerItem, matching: .images)
}
- 观察pickerItem变化,因为当它变化时,意味着用户已经选择了一张图片供我们加载。
VStack {
PhotosPicker("选择照片", selection: $pickerItem, matching: .images)
}
.onChange(of: pickerItem) {
Task {
selectedImage = try await pickerItem?.loadTransferable(type: Image.self)
}
}
加载完成后,我们可以调用loadTransferable(type:)选择器项,该方法告诉 SwiftUI 我们想要将实际的底层数据,从选择器项加载到 SwiftUI 图像中。如果成功,我们可以将结果值分配给该selectedImage属性。
调用
loadTransferable(type:)可能需要几秒钟才能完成,特别是对于全景图等大图片。
- 在某处显示加载的 SwiftUI 图像
selectedImage?
.resizable()
.scaledToFit()
多选
@State private var pickerItems = [PhotosPickerItem]()
@State private var selectedImages = [Image]()
...
VStack {
PhotosPicker("选择照片", selection: $pickerItems, maxSelectionCount: 3, matching: .images)
}
处理选择结果
.onChange(of: pickerItems) {
Task {
selectedImages.removeAll()
for item in pickerItems {
if let loadedImage = try await item.loadTransferable(type: Image.self){
selectedImages.append(loadedImage)
}
}
}
}
显示选择的图片
ScrollView {
ForEach(0..<selectedImages.count, id: \.self) { i in
selectedImages[i]
.resizable()
.scaledToFit()
}
}
另外,可以提供完全自定义的标签
PhotosPicker(selection: $pickerItems, maxSelectionCount: 3, matching: .images) {
Label("选择照片", systemImage: "photo")
}
限制可以导入的图片种类
.images在这里全面使用,这意味着我们将获得常规照片、屏幕截图、全景图等。您可以使用.any()、.all()和来应用更高级的过滤器.not(),并向它们传递一个数组。
PhotosPicker(selection: $pickerItems, maxSelectionCount: 3, matching: .any(of: [.images, .not(.screenshots)])) {
Label("Select a picture", systemImage: "photo")
}