DEV Community

GoyesDev
GoyesDev

Posted on

[SUI] LazyGrid

Mientras que un LazyVStack y un LazyHStack pueden agregar un solo item por fila o columna, respectivamente; un LazyVGrid y un LazyHGrid pueden agregar varios items por fila o columna, respectivamente.

Un GridItem describe una fila o una columna en un LazyHGrid o en un LazyVGrid, respectivamente. Cada GridItem define propiedades como espaciado, tamaño y alineación.

El tamaño de un GridItem es el número de elementos que caben en una fila o columna, es de tipo GridItem.Size y puede tomar los valores:

Ejemplo de implementación

Consideremos el caso de un LazyHGrid que puede agregar varios items por fila. Al definir la estructura, cada fila se define con un GridItem y, como se definen cuatro, entonces la grilla tendrá cuatro filas.

En este ejemplo, cada fila tiene una altura fija (i.e. .fixed(30), .fixed(60), .fixed(90), .fixed(10)), junto con el espaciado que va después de ellas (i.e. 1, 10, 20, 50).

Luego, se pasa la lista de elementos a la grilla por medio del bloque content. Notar que se construyen 300x5 = 1500 instancias de Color, con anchos y colores diferentes, que se distribuyen a lo largo de las 4 filas definidas de la grilla. El ancho es fijo, sin embargo, la altura cambia según el tamaño definido en el GridItem (debido a .fixed).

struct ContentView: View {
  let rows = [
    GridItem(.fixed(30), spacing: 1),
    GridItem(.fixed(60), spacing: 10),
    GridItem(.fixed(90), spacing: 20),
    GridItem(.fixed(10), spacing: 50)
  ]

  var body: some View {
    ScrollView(.horizontal) {
      LazyHGrid(rows: rows, spacing: 5) {
        ForEach(0..<300, id: \.self) { _ in
          Color.red.frame(width: 30)
          Color.green.frame(width: 40)
          Color.blue.frame(width: 20)
          Color.yellow.frame(width: 25)
          Color.purple.frame(width: 15)
        }
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Al usar .flexible para determinar el tamaño del GridItem, los componentes van a tomar tanto espacio como les sea posible, a no ser de que haya más de un .flexible y uno de ellos tenga maximum.

struct ContentView: View {
  let rows = [
    GridItem(.fixed(30), spacing: 1),
    GridItem(.flexible(minimum: 60), spacing: 10),
    GridItem(.fixed(90), spacing: 20),
    GridItem(.fixed(10), spacing: 50)
  ]

  var body: some View {
    ScrollView(.horizontal) {
      LazyHGrid(rows: rows, spacing: 5) {
        ForEach(0...300, id: \.self) { _ in
          Color.red.frame(width: 30)
          Color.green.frame(width: 40)
          Color.blue.frame(width: 20)
          Color.yellow.frame(width: 25)
          Color.purple.frame(width: 15)
        }
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode


struct ContentView: View {
  let rows = [
    GridItem(.fixed(30), spacing: 1),
    GridItem(.flexible(minimum: 60), spacing: 10),
    GridItem(.fixed(90), spacing: 20),
    GridItem(.flexible(maximum: 20), spacing: 50)
  ]

  var body: some View {
    ScrollView(.horizontal) {
      LazyHGrid(rows: rows, spacing: 5) {
        ForEach(0...300, id: \.self) { _ in
          Color.red.frame(width: 30)
          Color.green.frame(width: 40)
          Color.blue.frame(width: 20)
          Color.yellow.frame(width: 25)
          Color.purple.frame(width: 15)
        }
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Tanto .flexible como .fixed representan una sola fila (para el caso de LazyHGrid). Usar .adaptive provoca que aparezcan tantas filas como sea posible, conservando las mismas proporciones y espacio entre las vistas. Si queda espacio disponible, entonces expande los items para conservar el mismo espacio entre ellos.

struct ContentView: View {
  let rows = [
    GridItem(.adaptive(minimum: 30, maximum: 100), spacing: 50)
  ]

  var body: some View {
    ScrollView(.horizontal) {
      LazyHGrid(rows: rows, spacing: 5) {
        ForEach(0...300, id: \.self) { _ in
          Color.red.frame(width: 30)
          Color.green.frame(width: 40)
          Color.blue.frame(width: 20)
          Color.yellow.frame(width: 25)
          Color.purple.frame(width: 15)
        }
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)