Los iPads y Macs pueden presentar más contenido en la pantalla, así que si se necesita presentar más de una columna, se puede usar el componente Table
-
init(_:selection:sortOrder:columns:):dataes la información de la tabla.selectionson los identificadores de las filas seleccionadas.sortOrderes un arreglo con los descriptores de orden de tipoSortComparator.columnscon las vistas para crear las columnas. -
init(of:selection:sortOrder:columns:rows:):datason los datos a mostrar.selectiones un arreglo con los identificadores de las filas seleccionadas.sortOrderson los descriptores (arreglo) de orden de la tabla.columnsson las vistas para crear las columnas.rowsvistas para crear las filas.
El contenido se define con los componentes TableColumn y TableRow
-
TableColumn.init(_:value:content:):textes el título de la columna.valuees elKeyPathde la propiedad que tiene los valores de la columna.contentdefine la vista a mostrar en la columna. -
TableRow.init(_:):valuees el valor de una fila para cada columna de la tabla.
Por defecto, el ancho de las columnas es determinado por el número de columnas en la tabla y el espacio disponible. Para cambiarlo, se usa:
-
TableColumn.width(_:): Ancho fijo. -
TableColumn.width(min:ideal:max:): Ancho flexible.
struct Person: Identifiable {
let givenName: String
let familyName: String
let emailAddress: String
let id = UUID()
var fullName: String { givenName + " " + familyName }
}
let people = [
Person(givenName: "Juan", familyName: "Chavez", emailAddress: "juanchavez@icloud.com"),
Person(givenName: "Mei", familyName: "Chen", emailAddress: "meichen@icloud.com"),
Person(givenName: "Tom", familyName: "Clark", emailAddress: "tomclark@icloud.com"),
Person(givenName: "Gita", familyName: "Kumar", emailAddress: "gitakumar@icloud.com")
]
struct ContentView: View {
var body: some View {
Table(people) {
TableColumn("Given Name", value: \.givenName)
TableColumn("Family Name", value: \.familyName)
TableColumn("E-Mail Address", value: \.emailAddress)
}
}
}
Seleccionando filas de una tabla
Se puede seleccionar una fila usando un Binding
struct ContentView: View {
@State private var selectedPeople = Set<Person.ID>()
var body: some View {
Table(people, selection: $selectedPeople) {
TableColumn("Given Name", value: \.givenName)
TableColumn("Family Name", value: \.familyName)
TableColumn("E-Mail Address", value: \.emailAddress)
}
Text("\(selectedPeople.count) people selected")
}
}
Para seleccionar una sola entrada, no hay que hacer nada más. Sin embargo, para seleccionar varias entradas, es necesario tener editMode activado en el ambiente. Para ello, entonces, se va a poner un EditButton:
struct ContentView: View {
@State private var selectedPeople = Set<Person.ID>()
var body: some View {
NavigationStack {
VStack {
Text("\(selectedPeople.count) people selected")
Table(people, selection: $selectedPeople) {
TableColumn("Given Name", value: \.givenName)
TableColumn("Family Name", value: \.familyName)
TableColumn("E-Mail Address", value: \.emailAddress)
}
}.toolbar {
EditButton()
}
}
}
}
Tablas con contenido estático
init(of:columns:rows:) permite construir una tabla con celdas estáticas, al especificar el tipo de dato de las filas en valueType, y luego pasando las filas en rows, por medio de instancias de TableRow.
A continuación se muestra cómo pintar la tabla de los ejemplos anteriores de forma estática:
struct ContentView: View {
var body: some View {
Table(of: Person.self) {
TableColumn("Given Name", value: \.givenName)
TableColumn("Family Name", value: \.familyName)
TableColumn("E-Mail Address", value: \.emailAddress)
} rows: {
TableRow(Person(givenName: "Juan", familyName: "Chavez", emailAddress: "juanchavez@icloud.com"))
TableRow(Person(givenName: "Mei", familyName: "Chen", emailAddress: "meichen@icloud.com"))
TableRow(Person(givenName: "Tom", familyName: "Clark", emailAddress: "tomclark@icloud.com"))
TableRow(Person(givenName: "Gita", familyName: "Kumar", emailAddress: "gitakumar@icloud.com"))
}
}
}
En este caso conviene usar el componte ForEach para crear las filas de forma estática:
let people = [
Person(givenName: "Juan", familyName: "Chavez", emailAddress: "juanchavez@icloud.com"),
Person(givenName: "Mei", familyName: "Chen", emailAddress: "meichen@icloud.com"),
Person(givenName: "Tom", familyName: "Clark", emailAddress: "tomclark@icloud.com"),
Person(givenName: "Gita", familyName: "Kumar", emailAddress: "gitakumar@icloud.com")
]
struct ContentView: View {
var body: some View {
Table(of: Person.self) {
TableColumn("Given Name", value: \.givenName)
TableColumn("Family Name", value: \.familyName)
TableColumn("E-Mail Address", value: \.emailAddress)
} rows: {
ForEach(people) {
TableRow($0)
}
}
}
}
Ordenar entradas de una tabla
Para hacer que las columnas de una tabla puedan servir como criterio de ordenamiento, se debe proveer un binding a un arreglo de instancias de tipo SortComparator con los keypaths para ordenar.
Cuando un sort descriptor cambia, se deben reordenar los datos manualmente, es decir: esta operación no la hace la tabla. Para ello, la documentación sugiere usar onChange(of:initial:_:) para detectar los cambios.
struct ContentView: View {
@State private var sortOrder = [KeyPathComparator(\Person.givenName)]
@State private var people = [
Person(givenName: "Juan", familyName: "Chavez", emailAddress: "juanchavez@icloud.com"),
Person(givenName: "Mei", familyName: "Chen", emailAddress: "meichen@icloud.com"),
Person(givenName: "Tom", familyName: "Clark", emailAddress: "tomclark@icloud.com"),
Person(givenName: "Gita", familyName: "Kumar", emailAddress: "gitakumar@icloud.com")
]
var body: some View {
Table(people, sortOrder: $sortOrder) {
TableColumn("Given Name") { person in
HStack {
Image(systemName: "person")
Text(person.givenName)
}
}
.width(120)
TableColumn("Family Name", value: \.familyName)
.width(120)
TableColumn("E-Mail address", value: \.emailAddress)
}
.onChange(of: sortOrder) {
people.sort(using: sortOrder)
}
}
}




Top comments (0)