SwiftUI: componente ScrollView
Qué es ScrollView
El componente ScrollView
es uno de los componentes de SwiftUI
que permite mostrar todo el contenido de una vista que por su maquetación se sale de los márgenes visibles de la pantalla, tanto en la vertical como en la horizontal. Es un componente equivalente a UIScrollView
de UIKit
.
Aquí podéis consultar la documentación oficial
Para usarlo tenemos que incluir en su ViewBuilder
todas las vistas sobre las que se les quiere dar la capacidad de hacer scroll.
Scroll Vertical
ScrollView { VStack(spacing: 10) { ForEach(0..<100) { Text("Index: ($0)") } } .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center) } .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center) .background(Color.yellow.opacity(0.3))
Scroll Horizontal
ScrollView(.horizontal) { HStack(spacing: 10) { ForEach(0..<100) { Text("Index: ($0)") } } .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center) } .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center) .background(Color.yellow.opacity(0.3))
En la inicialización de ScrollView
debemos indicar la dirección que tendrá el propio scroll (por defecto es vertical
) y también podemos indicar si queremos que se muestre la barra indicadora del nivel del scroll (por defecto true
). Por último, se le pasarán las vistas que queramos incluir dentro del ScrollView
.
De esta forma el ScrollView
adaptará el contenido 'scolleable' dependiendo de las vistas que contenga.
También se puede indicar que el ScrollView
pueda hacer scroll tanto en la vertical como en la horizontal de la siguiente forma.
ScrollView([.vertical, .horizontal])
Es muy común que cuando tengamos TextField
en una pantalla, toda la pantalla esté contenida dentro de un ScrollView
para que podamos ver todo el contenido cuando se presente el teclado. Podéis consultar cómo hacer esto en este artículo.
Modificadores comunes para ScrollView
El componente ScrollView
comparte los mismos métodos de personalización que el componente View
y pueden ser consultados en el siguiente enlace.
Cómo mover el scroll programáticamente con ScrollViewReader (iOS 14)
A partir de iOS 14 Apple ha incluido el componente ScrollViewReader
que nos permite tener control para movernos en el contenido del ScrollView
.
Para usarlo debemos incluirlo como dentro del ScrollView
e incluir todas las vistas que hubieran estado en él dentro del ScrollViewReader
.
Cada uno de los componentes a los que podremos hacer scroll deberán tener definido un tag
para que podamos hacer referencia al item al que queremos movernos.
import SwiftUI import Combine struct ContentView: View { @State private var index: String = "" @State private var selectedIndex: Int? @State private var doScroll: Bool = false var body: some View { VStack { HeaderSectionView("ScrollViewReader") HStack(spacing: 15) { TextField("Index between 0-99", text: $index) .textFieldStyle(RoundedBorderTextFieldStyle()) .keyboardType(.numberPad) .onReceive(Just(index), perform: { value in let filtered = "(value)".filter { "0123456789".contains($0) } if filtered != value { self.index = "(filtered)" } }) Button("Scroll!") { UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil) doScroll = true } } ScrollView { ScrollViewReader { proxy in VStack { ForEach(0..<100) { if let selectedIndex = selectedIndex, selectedIndex == $0 { Text("Index: ($0)") .padding() .background(Color.red.opacity(0.3)) .tag($0) } else { Text("Index: ($0)") .padding() .tag($0) } } } .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center) .onReceive(Just(doScroll)) { value in if let index = Int(index), value { selectedIndex = index withAnimation { proxy.scrollTo(index, anchor: .center) } } doScroll = false } } } .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center) .background(Color.yellow.opacity(0.3)) } .padding() } }
En el ejemplo anterior se ha implementado un Button
que recoge el valor del TextField
. Este valor será el tag
del elemento al que queremos hacer scroll y lo haremos con la siguiente función:
proxy.scrollTo(index, anchor: .center)
El parámetro proxy
lo proporciona el ScrollViewReader
e implementa el método scrollTo
para mover el scroll.
Ejemplo
Puedes encontrar este ejemplo en https://github.com/SDOSLabs/SwiftUI-Test bajo el apartado ScrollView.
Rafael Fernández,
iOS Tech Lider