Apple anunció ayer las novedades en el kit de desarrollo de este año y unas de las que más darán que hablar son mejoras en SwiftUI y la llegada de nuevos elementos.
Algo que echábamos de menos en SwiftUI era la posibilidad de crear una especie de UICollectionView
y, aunque técnicamente todavía no ha llegado, ya podemos colocar nuestras vistas en un grid vertical u horizontal utilizando LazyVGrid
y LazyHGrid
respectivamente.
La noticia menos buena es que éstos sólo están disponibles para iOS14
y superior, así que si necesitas soportar iOS13
todavía no podrás beneficiarte de ellos.
Ejemplo de LazyVGrid
:
Imagina que estás creando una lista de los dispositivos que Apple tiene a la venta y los quieres mostrar en formato Grid, como si se tratase de un UICollectionView
con un UICollectionViewFlowLayout
.
Crea un nuevo fichero Devices.swift
y añade lo siguiente:
struct Device: Identifiable, Hashable {
let id = UUID()
let name: String
let iconName: String
}
enum DeviceRepository {
static let all = [
Device(name: "AirPods", iconName:"airpods"),
Device(name: "AirPods Pro", iconName:"airpodspro"),
Device(name: "AppleTV", iconName:"appletv"),
Device(name: "Apple Watch", iconName:"applewatch"),
Device(name: "HomePod", iconName:"homepod"),
Device(name: "iPad", iconName:"ipad"),
Device(name: "iPhone", iconName:"iphone"),
Device(name: "iPod", iconName:"ipod"),
Device(name: "Apple Pencil", iconName:"pencil.tip")
]
}
A continuación, añade otro nuevo fichero DeviceItem.swift
y crea la vista de la «celda», que consistirá en un icono y el nombre del dispositivo:
struct DeviceItem: View {
let device: Device
var body: some View {
VStack {
Image(systemName: device.iconName)
.font(.title)
Text(device.name)
.font(.caption)
.multilineTextAlignment(.center)
.foregroundColor(.primary)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.padding()
.background(Color(white: 0.95))
.cornerRadius(10)
.shadow(radius: 5)
}
}
Por último, abre el fichero ContentView.swift
y sustituye su contenido por lo siguiente:
struct ContentView: View {
// 1
let devices = DeviceRepository.all
// 2
let columns = [
GridItem(.flexible(minimum: 90), spacing: 20),
GridItem(.flexible(minimum: 90), spacing: 20),
GridItem(.flexible(minimum: 90), spacing: 20)
]
var body: some View {
NavigationView {
ScrollView {
// 3
LazyVGrid(columns: columns, spacing: 20) {
ForEach(devices, content: DeviceItem.init)
}
.padding(.all, 50)
.navigationTitle("Devices")
}
}
}
}
// 1
: Creamos un array con todos los dispositivos que vamos a mostrar// 2
: Esta es la parte más importante, donde configuramos el formato del grid. Existen tres maneras de configurarlo:- Usando
.flexible(...)
: especificamos el número de columnas que habrá, sin importar el espacio disponible que haya en la pantalla. En este ejemplo, estamos diciendo que haya exactamente 3 columnas, ya que el array contiene 3 elementos de este tipo. - Usando
.adaptive(minimum:)
: tendremos tantas columnas como sea posible en el espacio disponible. - Usando
.fixed(250)
: haremos que el contenido tenga una anchura fija, en este caso de 250 puntos.
- Usando
// 3
: UtilizamosLazyVGrid
(oLazyHGrid
) para que nuestra lista de dispositivos se muestre en formato grid vertical (u horizontal), pasando por parámetro la configuración de las columnas.
Así es como se ve utilizando la configuración de columnas actual, con tres elementos GridItem(.flexible(minimum: 90), spacing: 20)
. Fíjate que, aunque en orientación landscape hay suficiente espacio para introducir más elementos, sigue teniendo 3 columnas:
Si modificamos la configuración de las columnas y utilizamos la configuración adaptativa:
let columns = [
GridItem(.adaptive(minimum: 90), spacing: 20)
]
Observarás que ahora el número de elementos visible en cada orientación varía dependiendo del espacio disponible, teniendo hasta cinco items :
Si te ha gustado el artículo subscríbete a la newsletter para no perderte ninguno de los próximos posts que escriba.
👇👇👇
Únete a la newsletter para no perderte ningún nuevo tutorial: recibe un email cuando se publiquen nuevos artículos o vídeos y no pierdas la oportunidad de seguir aprendiendo.