Agrega un selector de imágenes con PhotosPicker en SwiftUI

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.

Simulador mostrando una pantalla donde presionando un botón podemos seleccionar una imagen de la galería de fotos y mostrarla.

Preparando la vista

Partiremos del siguiente View:

import SwiftUI
struct ProfileView: View {
// 1
@State var uiImage: UIImage? = nil
var body: some View {
VStack {
// 2
Image(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:

  1. Creamos una variable de estado llamada uiImage donde almacenaremos la imagen seleccionada en formato UIImage.
  2. Utilizamos el contenido de uiImage para crear un Image y aplicamos modificadores para asegurar que la imagen se muestre correctamente.

Agregando el PhotosPicker

import SwiftUI
// 1
import PhotosUI
struct ProfileView: View {
// 2
@State var imageSelection: PhotosPickerItem? = nil
@State var uiImage: UIImage? = nil
var body: some View {
VStack {
Image(uiImage: uiImage ?? UIImage())
.resizable()
.scaledToFill()
.frame(width: 200, height: 200)
.clipped()
.background(Color.gray.opacity(0.2))
// 3
photoPickerButton
}
}
// 4
var 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:

  1. Importamos PhotosUI, lo que nos permitirá acceder a las APIs necesarias para interactuar con la galería de fotos.
  2. Agregamos una variable de estado imageSelection, que almacenará la imagen seleccionada antes de ser convertida a UIImage.
  3. Indicamos el lugar donde estará el botón que mostrará el selector de fotos.
  4. 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 mediante shared()), 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 in
if 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:

Simulador mostrando una pantalla donde presionando un botón podemos seleccionar una imagen de la galería de fotos y mostrarla.

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)
}
Ejemplo de selector usando el modo 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)
Ejemplo de selector sin la barra accesorio

Comparte este artículo

Subscríbete a nuestro Newsletter

Mantente al día en el mundo de las aplicaciones móviles con nuestro blog especializado.

Artículos semanales

Todas las semanas artículos nuevos sobre el mundo de las aplicaciones móviles.

No spam

No te enviaremos spam, solo contenido de calidad. Puedes darte de baja cuando quieras.

Contenido de calidad

Nada de contenido generado de manera automática usando ChatGPT.

Recomendaciones

Tips indispensables sobre mejores prácticas y metodologías.

© 2024 AsyncLearn