Neuerungen der WWDC 2022 – Teil 5
Mit der neuen PhotosPicker
-View steht uns jetzt ein natives SwiftUI-Element zur Verfügung, um auf die Foto-Library zugreifen und Bilder auswählen zu können. In diesem Artikel gehe ich auf die grundlegende Funktionsweise von PhotosPicker
ein und zeige euch, wie ihr diese neue View nutzen könnt, um ein einzelnes Foto aus der Library auszuwählen und anzuzeigen.
Grundlagen
PhotosPicker
nutzt eine Instanz vom Typ PhotosPickerItem
, um die vom Nutzer gewählten Fotos abzubilden. Demnach braucht es ein Binding auf eine PhotosPickerItem
-Instanz, die man PhotosPicker
als Parameter übergibt. PhotosPicker
füllt dieses Binding mit den Daten der vom Nutzer gewählten Fotos.
Jenes Binding könnt ihr auf zwei Arten konfigurieren. Falls der Nutzer mehrere Fotos auswählen soll, kommt als zugrundeliegender Status ein Array von PhotosPickerItem
-Instanzen zum Einsatz. Soll nur ein einzelnes Bild wählbar sein, reicht als Status ein Optional vom Typ PhotosPickerItem
. In diesem Beispiel betrachte ich letztere Variante.
Um eine PhotosPicker
-Instanz zu erzeugen, braucht es in der einfachsten Variante nur zwei Parameter:
selection
: Das Binding auf denPhotosPickerItem
-Status, der die Daten zu den ausgewählten Fotos erhält. Wie beschrieben handelt es sich bei dem zugrundeliegenden Typ dieses Bindings entweder um[PhotosPickerItem]
(für die Auswahl mehrerer Bilder) oderPhotosPickerItem?
(für die Auswahl eines einzelnen Bildes).label
: Die Darstellung vonPhotosPicker
.PhotosPicker
ist letztlich ein einfacher Button, dessen Betätigung die Foto-Library öffnet. Mithilfe deslabel
-Parameters legt ihr das Aussehen jenes Buttons fest.
Zusätzlich gibt es noch diverse weitere optionale Parameter, mit denen sich PhotosPicker
zusätzlich konfigurieren lässt. Einer davon ist matching
. Über ihn legt ihr fest, welche Arten von Dateien aus der Foto-Library auswählbar sein sollen. Ihr habt hier unter anderem die Wahl zwischen Werten wie images
, livePhotos
oder videos
.
Das nachfolgende Listing skizziert einmal beispielhaft die Umsetzung einer einfachen PhotosPicker
-Instanz, die lediglich die Auswahl eines einzigen Bildes erlaubt. Wichtig hierbei: PhotosPicker
ist Teil des PhotosUI-Frameworks, das entsprechend importiert werden muss.
import PhotosUI
import SwiftUI
struct ContentView: View {
@State var selectedItem: PhotosPickerItem?
var body: some View {
PhotosPicker(selection: $selectedItem, matching: .images) {
Label("Select a photo", systemImage: "plus.app")
}
}
}
Zugriff auf das ausgewählte Foto
Der PhotosPicker
weist das gewählte Foto dem PhotosPickerItem
-Binding zu. So bleibt nun noch zu klären, wie man aus einem PhotosPickerItem
heraus auf das zugrundeliegende Bild zugreift.
PhotosPickerItem
selbst gewährt uns keinen direkten Zugriff auf das enthaltene Foto, was wohl mit den unterschiedlichen Mediendateien und -formaten zusammenhängt, die PhotosPickerItem
unterstützt (es lassen sich ja unter anderen auch Videos auswählen, die anders zu verarbeiten sind als Fotos).
Aus diesem Grund stellt PhotosPickerItem
eine Methode namens loadTransferable(type:)
zur Verfügung. Ähnlich wie bei der Arbeit mit NSItemProvider
fragt man so ab, ob das in PhotosPickerItem
enthaltene Medienelement einem spezifischen Typ entspricht. Das generischste Vorgehen besteht darin, gegen den Typ Data
zu prüfen und so die tatsächlichen Daten des gewählten Medienelements als Ergebnis zu erhalten. Diese Daten lassen sich dann beliebig weiter verarbeiten (zum Beispiel zur Anzeige eines Bildes via Image
-View).
Um mitzubekommen, wann über einen PhotosPicker
ein Bild ausgewählt und so das Binding des PhotosPickerItem
s gesetzt wurde, nutzt man den onChange(of:perform:)
-Modifier. Das nachfolgende Listing zeigt einmal ein vollständiges Beispiel zum Einsatz des PhotosPicker
inklusive Anzeige des gewählten Fotos. Dazu werden die ausgewerteten Bilddaten einem Status namens imageData
zugewiesen, die wiederum zur Darstellung des gewählten Bildes innerhalb der View dienen.
import PhotosUI
import SwiftUI
struct ContentView: View {
@State private var imageData: Data?
@State private var selectedItem: PhotosPickerItem?
var body: some View {
VStack {
PhotosPicker(selection: $selectedItem, matching: .images) {
Label("Select a photo", systemImage: "plus.app")
}
.onChange(of: selectedItem) { newValue in
Task {
if let data = try? await newValue?.loadTransferable(type: Data.self) {
await MainActor.run {
self.imageData = data
}
}
}
}
Divider()
if let imageData, let uiImage = UIImage(data: imageData) {
Image(uiImage: uiImage)
.resizable()
.scaledToFit()
}
Spacer()
}
}
}
Fazit
PhotosPicker
ist eine erfreuliche Ergänzung innerhalb des SwiftUI-Frameworks. Die Konfiguration der View ist simpel und man erhält so schnell und unkompliziert Zugriff auf die Foto-Library. Zwar erscheint das Auswerten der gewählten Bilddaten über die loadTransferable(type:)
-Methode eines PhotosPickerItem
recht aufwendig, erfüllt aber ihren Zweck. Und hat man dieses Vorgehen erst einmal verinnerlicht, stellt es bei der zukünftigen Arbeit mit PhotosPicker
und PhotosPickerItem
auch keine Hürde mehr da.
Euer Thomas
Schreibe einen Kommentar