PhotosPicker, from the PhotosUI framework, is a button that runs the whole photo-picking flow
for you. Bind a selection, filter what the user may pick, then load the result through
Transferable.
The Picker Button
Import PhotosUI. The one required parameter is a binding to a PhotosPickerItem?.
import PhotosUI
struct ContentView: View {
@State private var selectedPhoto: PhotosPickerItem?
var body: some View {
NavigationStack {
content
.toolbar {
PhotosPicker(selection: $selectedPhoto, matching: .images) {
Image(systemName: "pencil")
}
}
}
}
}
The matching parameter takes a PHPickerFilter: .images, .videos, .screenshots,
.livePhotos, and more. Combine filters with any, all, and not, for example
.all(of: [.screenshots, .panoramas]).
Multiple Selection
Bind an array of PhotosPickerItem instead, and cap the count with maxSelectionCount.
@State private var selectedPhotos: [PhotosPickerItem] = []
PhotosPicker(selection: $selectedPhotos, maxSelectionCount: 3) {
Image(systemName: "pencil")
}
Loading the Selection
PhotosPickerItem loads its content through loadTransferable(type:), an async function that
decodes any Transferable type. Run it in a task(id:) keyed on the selection, so a new pick
reloads.
.task(id: selectedPhoto) {
if selectedPhoto?.supportedContentTypes.first == .image {
image = try? await selectedPhoto?.loadTransferable(type: Image.self)
}
}
Check supportedContentTypes before decoding when the picker allows mixed media, so you load an
image as Image and a video as your movie type. A callback-based variant exists for code not
using Swift Concurrency.