Contenido del curso

Integración Nativa en iOS 18

Scroll nativo en iOS 18 con SwiftUI

Resumen

Las nuevas APIs de ScrollView en iOS 18 permiten mover la posición del scroll, detectar dónde se encuentra el usuario y reaccionar a la visibilidad de elementos sin recurrir a librerías externas ni a UIKit. Si desarrollas en SwiftUI y necesitas crear lectores, feeds o documentos largos, estas funciones reducen código y mejoran la experiencia.

¿Cómo funciona scrollPosition en SwiftUI?

La idea central es vincular el estado de tu scroll a una variable que SwiftUI pueda leer y modificar. Para eso declaras tres variables con @State: una para saber si estás al inicio, otra para el final y una tercera de tipo ScrollPosition que representa la posición actual del contenido [01:00].

Dentro del ScrollView colocas un VStack con tu contenido. el truco está en añadir el modificador scrollPosition al ScrollView y enlazarlo con esa variable de estado. Desde ese momento, cualquier cambio en la variable mueve el scroll, y cualquier movimiento del usuario actualiza la variable.

¿Qué hace scrollPosition en iOS 18? Es un modificador nativo de SwiftUI que conecta una variable @State con la posición real del ScrollView, permitiendo leer y escribir la posición de forma reactiva.

¿Cómo crear un botón ir al final?

Una vez enlazada la variable, mover el scroll es directo. Creas un botón con el texto ir al final y, dentro de su acción, envuelves el cambio en withAnimation para que la transición sea fluida [03:30].

La instrucción clave es scrollViewPosition.scrollTo(edge: .bottom). Ese parámetro edge define hacia qué borde del contenido se desplaza el scroll. Si cambias .bottom por .top, el mismo mecanismo te lleva al inicio del documento.

Para que el contenido sea suficientemente largo y notes el efecto, pega varios bloques de Lorem Ipsum y aplica un estilo de lectura mediante un modificador personalizado tipo readingStyle.

¿Cómo detectar la posición del scroll con onScrollGeometryChange?

Saber cuándo mostrar un botón ir al inicio requiere escuchar el movimiento del scroll en tiempo real. Aquí entra onScrollGeometryChange, una función que se dispara cada vez que cambia la geometría del scroll [06:00].

La firma pide un tipo a observar, en este caso for: Bool.self, y un closure con la geometría geo. Dentro calculas el valor absoluto de geo.contentOffset.y y lo comparas contra geo.contentInsets.top más un topPadding de referencia.

  • contentOffset.y: indica cuánto se ha desplazado el contenido en el eje vertical.
  • contentInsets.top: representa el espacio reservado por el toolbar o navigation title.
  • topPadding: margen extra que defines tú para ajustar cuándo activar la condición.

Cuando la condición se cumple, ejecutas un action con dos parámetros, oldValue y newValue, y actualizas la variable booleana showGoToTopButton dentro de withAnimation. así controlas cuándo aparece o desaparece el botón flotante.

¿Cómo agregar un botón flotante con overlay?

El botón ir al inicio se monta como overlay sobre el ScrollView. Lo envuelves en un if showGoToTopButton para que solo aparezca cuando estás lejos del tope.

La acción del botón vuelve a usar withAnimation y scrollTo(edge: .top). Para el estilo visual aplicas buttonStyle(.borderedProminent) y reposicionas con un offset(y: -350) que lo ancla justo debajo del toolbar.

¿Cuándo se ejecuta onScrollGeometryChange? Cada vez que cambia algún valor geométrico del ScrollView, como el offset o los insets. Es la forma nativa de iOS 18 para reaccionar al scroll sin gestos manuales.

¿Cómo saber si el usuario llegó al final del documento?

Detectar el final del contenido tiene un giro interesante. Usas safeAreaInset(edge: .bottom) para colocar un texto fijo en la parte inferior que diga aún queda más por leer o estás al final según corresponda [11:30].

Dentro de un HStack agregas Spacer a los lados, padding vertical y un background(.ultraThinMaterial) para que el texto se lea sobre cualquier fondo sin transparencias incómodas.

El problema es que la variable atTheBottom no cambia sola. La solución es duplicar un fragmento del texto al final del contenido y aplicarle el modificador onScrollVisibilityChange.

¿Qué hace onScrollVisibilityChange?

Este modificador se ejecuta cuando un elemento entra o sale del área visible del scroll. Recibe un threshold que define qué porcentaje del elemento debe verse para disparar la acción.

  • Con threshold: 0.2, la función se activa cuando el 20% del texto es visible.
  • El closure recibe un booleano que indica si el elemento está visible o no.
  • Dentro envuelves la actualización en withAnimation y asignas ese valor a atTheBottom.

De esta manera, cuando el usuario hace scroll y el texto marcador aparece en al menos un 20%, la variable cambia a true y el mensaje en la parte inferior se actualiza automáticamente [16:00].

¿Por qué importan estas APIs nativas de iOS 18?

Antes de iOS 18, lograr este comportamiento implicaba gestos personalizados, cálculos manuales con GeometryReader o caer directamente en UIKit. Ahora SwiftUI ofrece tres piezas conectadas que cubren la mayoría de los casos.

  • scrollPosition para leer y escribir la posición.
  • onScrollGeometryChange para reaccionar a la geometría.
  • onScrollVisibilityChange para detectar visibilidad de elementos.

Si estás construyendo una app de lectura, un feed largo o cualquier vista con contenido extenso, estas funciones simplifican el código y mejoran el rendimiento. ¿Ya las probaste en tu proyecto? Cuéntame qué caso de uso le darías primero.