diegoRodicio

Está documentación está a túa disposición sin ningún custo económico. Sen embargo, para a súa elaboración dedico moito tempo e recursos, polo que agradecería unha colaboración co que consideres oportuno. Gracias.

View Categories

ForEach

A primeira vista, ForEach parece só un bucle na linguaxe de programación Swift.

Sen embargo, ForEach é algo moi diferente:

ForEach é unha estrutura de vista SwiftUI deseñada para xerar múltiples vistas mediante un bucle a través dun conxunto de datos como unha matriz ou un rango.

Ou o que é o mesmo, ForEach

  • É un tipo de vista que se utiliza para iterar sobre unha colección de datos
  • Crea vistas para cada elemento desa colección.
  • É similar a un bucle for-in en Swift, pero úsase específicamente para crear vistas dinámicas en función dos elementos dunha colección.

Aquí tes unha exemplo básico de como funciona ForEach cun rango, onde repetimos unha vista Text 9 veces (do 1 ao 9):

ForEach (1 ..< 10) { numero in
    Text("Número \(numero)")
}

\.self #

\.self é unha referencia ao propio valor da instancia ou do obxecto co que estás a traballar. É útil en varios contextos, especialmente cando se traballa con vistas.

Así, por exemplo, cando defines unha List (unha vista (View) de lista que veremos no seguinte tema), ás veces necesitas especificar como identificar cada elemento. O identificador pode ser unha propiedade única (como un id ou UUID), pero tamén podes usar \.self se os elementos da colección son únicos por si mesmos (por exemplo, se son de tipo String ou Int -tecnicamente porque cumpren o protocolo Hashable-).

let nomes = ["Diego", "Marta", "Mario"]

struct Contido: View {
    var body: some View {
        List(nomes, id: \.self) { nome in
            Text(nome)
        }
    }
}

Aquí, \.self indica que cada elemento da lista é único e que pode ser identificado polo seu propio valor.

Máis detalles. Utilizamos \.self: #

  • Cando queremos referirnos ao obxecto completo:
    • Por exemplo, se os elementos son tipos simples (String, Int, etc.) – que implementan o protocolo Hashable-.
    • Traballas con tipos complexos que implementan o protocolo Hashable, pero desexamos identificalos polo obxecto enteiro en vez dunha propiedade específica.
  • Usar \.self en lugar de definir un identificador específico é apropiado cando estás seguro de que os valores son únicos.

ForEach con máis detalle #

Un bucle ForEach funciona do seguinte xeito:

ForEach(data, id: \.self) { item in
    // Vista que se repetirá para cada elemento na colección
    Text(item)
}

Así,

  • data é a colección de datos que desexas iterar, como un array, unha lista ou unha secuencia.
  • id é un parámetro requirido que identifica de xeito único cada elemento da colección. No exemplo, usamos \.self para identificar elementos por si mesmos.
    • Tal e como explico no punto anterior, emprego \.self entre outros, para coleccións de tipos sinxelos como cadeas ou números.
    • Con todo, podes personalizar isto segundo as túas necesidades, especialmente se traballas con tipos de datos máis complexos.
  • O peche { item in ... } especifica como se debe crear unha vista para cada elemento na colección. item é a variable que representa un elemento individual en cada iteración.
    • No interior do peche, defines a vista que se creará para cada elemento.
    • No exemplo anterior, creamos un Text que mostra o elemento actual, pero podes crear calquera tipo de vista que desexes.

Cando utilizas ForEach desta maneira, SwiftUI encárgase automáticamente de crear as vistas necesarias para cada elemento na colección.

  • Se a colección cambia, por exemplo, debido á adición ou eliminación de elementos, SwiftUI actualizará automáticamente as vistas en consecuencia.
  • Isto fai que sexa unha forma potente de xerar vistas dinámicas baseadas en datos.

Exemplo #

import SwiftUI

struct ContentView: View {
    let items = ["Mazá","Plátano","Cereixa","Dátil"]
    var body: some View {
        
        VStack {
            ForEach (1 ..< 10) { numero in
                Text("Número: \(numero)")
            }
        }
        
        Divider()
        
        VStack {
            ForEach ((1 ..< 10), id: \.self) { numero in
                Text("Outro Número: \(numero)")
            }
        }
        
        Divider()
        
        VStack {
            List {
                ForEach(items, id: \.self) { item in
                    Text(item)
                }
            }
        }
    }
}