SwiftUI控件之 PhotosPicker
在 SwiftUI 中,有一个特殊的Picker(选择器),叫做PhotosPicker(相册选择器),使用它可以帮助快速获取手机相册中的照片。
创建一个 PhotosPicker
PhotosPicker本身并不属于 SwiftUI这个模块中,它属于PhotosUI模块,所以我们首先需要在头部导入这个模块:1
import PhotosUI
使用 @State 定义一个变量用来和PhotosPicker进行绑定:1
var selectedImages: PhotosPickerItem?
创建PhotoPicker:1
PhotosPicker("选择喜欢的照片", selection: $selectedImages)
此时的效果如下:

注意:上图的效果为 iOS 17 以后的效果。
因为相册里面的照片属于用户的敏感隐私数据,所以访问的时候会有隐私数据的提示。一般情况下,Apple 希望我们在隐私设置中添加访问敏感隐私数据的使用说明。
点击我们都项目根目录,在TARGETS中找到Info选项,在Custom iOS Target Properties中添加一个访问手机相册说明。

添加的记录如下,它是以Key-Value的形式存在的:

使用选中后的照片
使用PhotosPicker选中后的照片为 PhotosPickerItem类型,我们要想让选中的照片使用Image进行显示需要使用 loadTransferable(type:completionHandler:) 方法,具体使用如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26struct ContentView: View {
var selectedImages: PhotosPickerItem?
var avatarImage: Image?
var body: some View {
VStack {
PhotosPicker("选择喜欢的照片", selection: $selectedImages)
// 非空时显示
if let avatarImage {
avatarImage
.resizable()
.frame(width: 200, height: 200)
}
}
// 当前 selectedImages的值发生变化时调用
.onChange(of: selectedImages) { _ in
// 创建一个异步任务
Task {
// 将选中的 PhotosPickerItem 类型转换为要显示的 Image
if let image = try? await selectedImages?.loadTransferable(type: Image.self) {
avatarImage = image
return
}
}
}
}
}
在上面的代码中,实现的步骤如下:
- 使用
@State定义一个Image类型的变量用来接收转换后的照片; - 使用
onChange修饰器监听selectedImages变量值的的变化,当发生变化时将新的值转换为Image进行显示; - 转换的过程中使用了
Task创建了异步任务配合loadTransferable方法使用; - 当
avataImage的值不为nil时显示照片。
配置 PhotosPicker 可选择的范围
在 iOS ,我们平时拍的照片、截图、录的视频或者下载保存的视频都是存储在相册中的,PhotosPicker提供了一个matching参数用来设置应用可以选择的相册范围。
例如,如果想要应用只能选择视频,可以像下面这样设置:1
PhotosPicker("选择喜欢的照片", selection: $selectedImages, matching: .videos)
它来提供了很多的范围可选,例如:
panoramas:全景照片;images: 所有照片;videos: 所有视频;screenshots: 截图……