Table of Contents
La llegada de SwiftUI ha supuesto una revolución en el mundo del desarrollo iOS, simplificando la creación de interfaces de usuario con su sintaxis declarativa y sus potentes funciones. La introducción de ScrollTargetBehavior en SwiftUI es otro salto adelante, que promete agilizar aún más el desarrollo de interfaces sofisticadas y fáciles de usar. Este artículo profundiza en los matices de esta nueva característica, explorando cómo mejora la experiencia de desarrollo y abre nuevas posibilidades en el diseño de interfaz de usuario.
La esencia de ScrollTargetBehavior
ScrollTargetBehavior
marca una mejora significativa en la forma en que los desarrolladores pueden manejar el desplazamiento en SwiftUI. No es sólo una nueva herramienta; es un cambio de paradigma en la creación de interfaces de desplazamiento fluidas e intuitivas. Esta característica permite a los desarrolladores definir cómo se comporta una vista cuando un usuario se desplaza a un objetivo específico dentro de un ScrollView. Es como tener una herramienta de precisión donde antes sólo se tenía un martillo. Sólo está disponible a partir de iOS 17.
Principales ventajas
- Control preciso del desplazamiento: Los desarrolladores ahora pueden dictar la posición de un elemento desplazado dentro de un ScrollView. Tanto si deseas que un elemento se sitúe en el centro, como en el borde anterior o posterior, todo es posible con un simple modificador.
- Experiencia de usuario mejorada: Los comportamientos de desplazamiento suaves y predecibles son cruciales para la satisfacción del usuario. Con
ScrollTargetBehavior
, alcanzar este nivel de refinamiento es más accesible, lo que conduce a interfaces que se sienten más sensibles y naturales. - Interacciones personalizables: Dependiendo del contexto de tu aplicación, es posible que necesite diferentes comportamientos de desplazamiento. Esta nueva función ofrece la flexibilidad de adaptar estos comportamientos a las necesidades específicas de tu aplicación, mejorando tanto la funcionalidad como la estética.
- Código simplificado: La implementación de una lógica de desplazamiento compleja solía requerir un código prolijo e intrincado.
ScrollTargetBehavior
reduce esta complejidad, lo que permite un código más limpio y fácil de mantener.
Aplicaciones en el mundo real
Las implicaciones de ScrollTargetBehavior
son amplias y variadas. He aquí un vistazo a lo que permite:
Creación de galerías y carruseles intuitivos
Imagina una galería de fotos o un carrusel de productos. Con ScrollTargetBehavior
, los desarrolladores pueden garantizar que, a medida que los usuarios se desplacen por los elementos, cada nueva selección se centre suavemente en la pantalla, creando una experiencia de navegación elegante y fluida.
Elaboración de contenidos educativos y tutoriales
Para las aplicaciones que ofrecen contenidos educativos o tutoriales paso a paso, guiar a los usuarios a través del material resulta más intuitivo. Los desarrolladores pueden programar ScrollView para que se centre en cada nuevo contenido de una forma orgánica y deliberada.
Mejora la navegación en aplicaciones con muchos datos
En aplicaciones en las que la presentación de los datos es clave, como los cuadros de mando financieros o las herramientas de elaboración de informes, ScrollTargetBehavior
puede utilizarse para navegar rápidamente a puntos o secciones de datos específicos, facilitando la exploración de información compleja.
Implementación de un UIPageViewController en SwiftUI
Vamos a compartir un enfoque personalizado para utilizar esta nueva característica para implementar algo así como nuestro conocido UIPageViewController de UIKit.
PagedIndexViewModifier
es un modificador de vista SwiftUI que permite crear una vista de desplazamiento paginado, donde el contenido se divide en páginas discretas, y el índice de la página actual se actualiza a medida que el usuario se desplaza. Aquí tienes un desglose paso a paso de la implementación de este modificador:
Paso 1: Define la estructura del modificador de vista
Empieza por definir una estructura PagedIndexViewModifier
que se ajuste al protocolo ViewModifier
.
struct PagedIndexViewModifier: ViewModifier {
@Binding var index: Int
@State private var offset: CGPoint = .zero
...
}
@Binding var index
: Este binding permite al modificador actualizar el índice de la página actual.@State private var offset
: Esta variable de estado rastrea el desplazamiento de desplazamiento actual.
Paso 2: Implantar el cuerpo
El cuerpo del ViewModifier
es donde se define el comportamiento de desplazamiento.
func body(content: Content) -> some View {
GeometryReader { contentProxy in
...
}
}
- Utiliza un
GeometryReader
para medir el tamaño del contenido.
Paso 3: Configurar el ScrollView
Dentro del cuerpo, configura un ScrollView
y un LazyVStack
para tu contenido. Dar a su contenido un ancho completo y una altura completa
ScrollView {
LazyVStack(spacing: 0) {
content
.frame(width: contentProxy.size.width,
height: contentProxy.size.height)
}
...
}
- Esto crea una vista de desplazamiento vertical con el contenido estirado a toda la anchura y altura de su contenedor.
Paso 4: Seguimiento del desplazamiento
Utiliza un GeometryReader
dentro del LazyVStack
para rastrear el desplazamiento.
.background(GeometryReader { geometry in
Color.clear
.preference(key: ScrollOffsetPreferenceKey.self,
value: geometry.frame(in: .named("scroll")).origin)
})
- Este fondo invisible lee el desplazamiento de desplazamiento y lo proporciona a la vista adjunta utilizando una
PreferenceKey
personalizada.
Paso 5: Actualizar el índice actual
Reacciona a los cambios en el desplazamiento para actualizar el índice de la página actual.
.onPreferenceChange(ScrollOffsetPreferenceKey.self) { value in
self.offset = value
changeIndexIfNeeded(with: value, contentSize: contentProxy.size)
}
- Esta llamada de
offset
actualiza el desplazamiento y llama achangeIndexIfNeeded
para calcular el nuevo índice de página.
Paso 6: Aplicar la lógica del cambio de índice
Define changeIndexIfNeeded
para actualizar el estado del índice en función de la posición de desplazamiento actual.
private func changeIndexIfNeeded(with scrollValue: CGPoint, contentSize: CGSize) {
let yPoint = Double(scrollValue.y)
if yPoint == 0 && index == 0 { return }
let height = contentSize.height
guard yPoint.truncatingRemainder(dividingBy: height) == 0 else { return }
let currentIndex = index
let expectedIndex = Int(abs(yPoint / (height)))
if expectedIndex == currentIndex { return }
index = expectedIndex
}
- Esta función calcula el índice de la página actual a partir del desplazamiento y actualiza el enlace del
index
.
Paso 7: Gestionar los cambios de índice
Incrusta tu LazyVStack para usar onChange
para desplazarse al nuevo índice cuando cambie.
LazyVStack {
ScrollViewReader { svReaderProxy in
...
.onChange(of: index) { oldValue, newValue in
guard oldValue != newValue else { return }
svReaderProxy.scrollTo(newValue)
}
}
- Esto asegura que cuando el índice se actualiza externamente, la vista de desplazamiento se desplaza a la página correcta.
Paso 8: Crea la extensión
Amplia View
para utilizar el modificador con mayor comodidad.
extension View {
func indexedPageView(_ index: Binding<Int>) -> some View {
modifier(PagedIndexViewModifier(index: index))
}
}
- Esto permite que cualquier
View
adopte fácilmente el comportamiento de desplazamiento paginado.
Paso 9: Definir la clave de preferencia
Finalmente, define el ScrollOffsetPreferenceKey
para pasar el desplazamiento a través de las preferencias.
fileprivate struct ScrollOffsetPreferenceKey: PreferenceKey {
static var defaultValue: CGPoint = .zero
static func reduce(value: inout CGPoint, nextValue: () -> CGPoint) { }
}
- Esta tecla de preferencias actúa como canal de comunicación entre la vista de desplazamiento y el modificador de vista.
Hacerlo funcionar
Para ver un ejemplo de cómo utilizarlo vamos a compartir un código de ejemplo de 10 páginas Hello World
mostrando cada índice.
struct ContentView: View {
@State var index: Int = 0
var body: some View {
VStack {
ForEach(1...10, id: \.self) { index in
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, world! \(index)")
}.id(index)
}
.indexedPageView($index)
}
.ignoresSafeArea()
}
Con estos pasos, ahora puedes crear una experiencia de desplazamiento paginado en tus aplicaciones SwiftUI, completa con lazy loading y seguimiento de índice. El modificador PagedIndexViewModifier
hace que sea fácil añadir esta funcionalidad a cualquier vista desplazable, mejorando tanto el atractivo estético como la experiencia de usuario de tu aplicación.
En caso de necesitar un scroll horizontal, podrías añadir un valor Binding para establecer el eje horizontal del ScrollView y un LazyHStack en su lugar. Así podrías cambiar tu layout fácilmente.
Para acceder al archivo completo con la implementación detallada, puede visitar el siguiente enlace de GitHub: Archivo Swift completo en GitHub. Aquí encontrarás el código fuente completo, listo para su revisión y uso en tus proyectos.
Conclusión
ScrollTargetBehavior
de SwiftUI es más que una actualización incremental; es un testimonio de las crecientes capacidades de SwiftUI en la entrega de soluciones avanzadas de interfaz de usuario. Para los desarrolladores, simplifica la creación de interfaces complejas, interactivas e intuitivas. Para los usuarios, eleva la experiencia de interactuar con las aplicaciones, haciéndolas más atractivas y fáciles de navegar. A medida que SwiftUI sigue evolucionando, características como ScrollTargetBehavior
consolidan su posición como un potente marco para el desarrollo moderno de iOS, permitiendo a los desarrolladores crear mejores aplicaciones con menos esfuerzo.
Referencias
Para explorar más a fondo las funcionalidades y aplicaciones del ScrollTargetBehavior
de SwiftUI, y para estar al día de los últimos desarrollos y mejores prácticas en SwiftUI, los siguientes recursos son inestimables:
1. Documentación de SwiftUI por Apple:
- Visión general de ScrollTargetBehavior: Profundiza en la documentación oficial de Apple para una comprensión en profundidad de ScrollTargetBehavior en SwiftUI.
2. Tutoriales SwiftUI:
- Tutoriales SwiftUI de Apple: Una guía completa para iniciarse en SwiftUI, que ofrece una serie de tutoriales desde temas básicos hasta avanzados.
3. Sesiones de la WWDC sobre SwiftUI:
- Vídeos de la WWDC de Apple: Mira las sesiones de la Conferencia Mundial de Desarrolladores de Apple, donde los ingenieros de Apple presentan nuevas funciones y ofrecen información sobre SwiftUI.
Author
-
Aitor is an enthusiastic iOS Engineer eager to contribute to team success through hard work, attention to detail and excellent organizational skills. Clear understanding of iOS Platforms and Clean Code Principles and training in Team Management. Motivated to learn, grow and excel in Software Engineering.
Ver todas las entradas
More to Explore