Agrega un selector de imágenes con PhotosPicker en SwiftUI
Libranner Santos
03 enero, 20243min de lectura
En ocasiones, es necesario permitir a los usuarios seleccionar imágenes de su galería de fotos, como en el caso común de elegir una foto de perfil. En este artículo, exploraremos cómo lograr esto de manera rápida y sencilla utilizando SwiftUI y PhotosPicker
.
Preparando la vista
Partiremos del siguiente View
:
import SwiftUIstruct ProfileView: View {// 1@State var uiImage: UIImage? = nilvar body: some View {VStack {// 2Image(uiImage: uiImage ?? UIImage()).resizable().scaledToFill().frame(width: 200, height: 200).clipped().background(Color.gray.opacity(0.2))}}}
Lo que estamos haciendo en este código:
- Creamos una variable de estado llamada
uiImage
donde almacenaremos la imagen seleccionada en formatoUIImage
. - Utilizamos el contenido de
uiImage
para crear unImage
y aplicamos modificadores para asegurar que la imagen se muestre correctamente.
Agregando el PhotosPicker
import SwiftUI// 1import PhotosUIstruct ProfileView: View {// 2@State var imageSelection: PhotosPickerItem? = nil@State var uiImage: UIImage? = nilvar body: some View {VStack {Image(uiImage: uiImage ?? UIImage()).resizable().scaledToFill().frame(width: 200, height: 200).clipped().background(Color.gray.opacity(0.2))// 3photoPickerButton}}// 4var photoPickerButton: some View {PhotosPicker(selection: $imageSelection,matching: .images,photoLibrary: .shared()) {Image(systemName: "camera.circle.fill").font(.system(size: 50)).foregroundColor(.gray)}}}
Nuestra pantalla está tomando forma:
- Importamos
PhotosUI
, lo que nos permitirá acceder a las APIs necesarias para interactuar con la galería de fotos. - Agregamos una variable de estado
imageSelection
, que almacenará la imagen seleccionada antes de ser convertida a UIImage. - Indicamos el lugar donde estará el botón que mostrará el selector de fotos.
- Creamos el código para el botón.
PhotosPicker
recibe como parámetros una variable donde se almacenará la foto seleccionada, el filtro en este caso solo para imágenes, la biblioteca de fotos a la que queremos acceder (en este caso la compartida medianteshared()
), y finalmente, una vista que representará el botón.
Convertir a UIImage
Para completar la tarea, necesitamos convertir de PhotosPickerItem
a UIImage
. Agreguemos este modificador al VStack
:
.onChange(of: imageSelection) {Task { @MainActor inif let data = try? await imageSelection?.loadTransferable(type: Data.self) {uiImage = UIImage(data:data)return}}}
Con este código, cada vez que imageSelection
cambie, ejecutaremos una tarea en el MainActor
. Esta tarea convierte el contenido de imageSelection
a Data
y luego convierte de Data
a UIImage
para almacenarlo en uiImage
.
Dado que la vista Image
ya utiliza la variable de estado uiImage
, todo funcionará como se espera:
Opciones de configuración para el PhotosPicker
Existen varias formas de modificar la apariencia y funcionalidades del selector utilizando distintos modificadores.
Puedes ajustar la presentación del selector utilizando photosPickerStyle(_:)
. Tienes opciones como presentation
(el modo por defecto), compact
e inline
.
Si deseas utilizar el modo inline
, puedes crear nuestro botón de la siguiente manera:
var photoPickerButton: some View {PhotosPicker(selection: $imageSelection,matching: .images,photoLibrary: .shared()) {Image(systemName: "camera.circle.fill").font(.system(size: 50)).foregroundColor(.gray)}.photosPickerStyle(.inline)}
Puedes deshabilitar funcionalidades específicas utilizando photosPickerDisabledCapabilities(_:)
. Por ejemplo, para desactivar la barra de búsqueda, puedes agregar este modificador al PhotosPicker
:
.photosPickerDisabledCapabilities([.search])
También puedes ocultar la barra accesorio usando el modificador:
.photosPickerAccessoryVisibility(.hidden)