Pull to refresh con SwiftUI
Libranner Santos
08 noviembre, 20232min de lectura
En ocasiones, es necesario brindar a los usuarios la posibilidad de actualizar una lista mediante gestos. En las plataformas de Apple, es común utilizar el gesto "pull-to-refresh". Este gesto implica deslizar hacia abajo en una vista, generalmente una List
, para actualizar los datos.
Para implementar este comportamiento en SwiftUI, utilizamos el modificador refreshable(action:)
. Este modificador nos permite proporcionar un cierre que se ejecutará cuando el usuario realice el gesto.
Veamos un ejemplo:
struct TaskListView: View {private var todos : [TodoItem] = [.init(content: "Clean house"),.init(content: "Cook"),.init(content: "Go to work")]var body: some View {NavigationStack {List {ForEach(todos) { todoItem inText(todoItem.content)}}.refreshable {await refresh()}.navigationTitle("My Tasks")}}private func refresh() async {try? await Task.sleep(nanoseconds: 1_000_000)}}
Este código presenta una List
que muestra una lista de elementos Text
. El modificador refreshable
se aplica a esta List
, y contiene un closure que ejecuta la tarea asíncrona refresh
.
Es importante destacar que no es necesario envolver el código asíncrono con Task
, ya que el closure que se espera en refreshable
puede ser async
, como se muestra en su definición:
public func refreshable(action: @escaping @Sendable () async -> Void) -> some View
La variable de entorno refresh
Cuando utilizamos refreshable
, el contenido del closure se almacena en una variable de entorno. Por lo tanto, podemos acceder a él utilizando el siguiente código:
import SwiftUIstruct MyChildView: View {@Environment(\.refresh) private var refreshFunctionvar body: some View {Button("Run") {await refreshFunction()}}
Es fundamental recordar que esto solo es posible si la vista donde usamos la variable de entorno es una vista hija de la vista donde definimos refreshable
previamente.