This practical, example-based article will walk you through a couple of different ways to group items in a List in SwiftUI (caution: you will see a lot of code).
Using listStyle modifier
TL;DR
You can also use the listStyle modifier on your List to change its appearance. There are two styles that are commonly used for grouping items: .grouped and .insetGrouped. The .grouped style creates a list with rounded corners and separators between sections and items. The .insetGrouped style creates a list with inset margins and separators between items only.
List {
// sections and items
}
.listStyle(.grouped)
Complete example
Screenshot:
The full code:
//
// GroupedList.swift
// Examples
//
// Created by Sling Academy on 19/04/2023.
//
import SwiftUI
struct Item: Identifiable {
let id = UUID()
let name: String
let category: String
}
struct GroupedList: View {
let items = [
Item(name: "Apple", category: "Fruits"),
Item(name: "Banana", category: "Fruits"),
Item(name: "Orange", category: "Fruits"),
Item(name: "Carrot", category: "Vegetables"),
Item(name: "Broccoli", category: "Vegetables"),
Item(name: "Spinach", category: "Vegetables")
]
func groupByCategory(_ items: [Item]) -> [(String, [Item])] {
let grouped = Dictionary(grouping: items, by: { $0.category })
return grouped.sorted(by: { $0.key < $1.key })
}
var body: some View {
List {
ForEach(groupByCategory(items), id:\.0) { pair in
Section(header:
Text(pair.0)
.font(.title2)
.foregroundColor(.blue)
) {
ForEach(pair.1) { item in
Text(item.name)
}
}
}
}
.listStyle(.insetGrouped)
}
}
struct GroupedList_Previews: PreviewProvider {
static var previews: some View {
GroupedList()
}
}
Using the groupBy() method
TL;DR
The second option is to use the groupBy() method on your data collection to create an array of key-value pairs, where the key is the grouping criterion and the value is an array of items that belong to that group. You can then use a ForEach loop to iterate over the key-value pairs and create a Section for each pair.
List {
ForEach(groupByCategory(items)) { pair in
Section(header: Text(pair.key)) {
ForEach(pair.value) { item in
Text(item.name)
}
}
}
}
Complete example
Screenshot:
The full code:
//
// GroupedList.swift
// Examples
//
// Created by Sling Academy on 19/04/2023.
//
import SwiftUI
struct Item: Identifiable {
let id = UUID()
let name: String
let category: String
}
struct GroupedList: View {
let items = [
Item(name: "Dog", category: "Animals"),
Item(name: "Cat", category: "Animals"),
Item(name: "Computer", category: "Devices"),
Item(name: "iPhone", category: "Devices"),
Item(name: "Television", category: "Devices"),
Item(name: "Car", category: "Vehicles"),
Item(name: "Truck", category: "Vehicles"),
Item(name: "Bike", category: "Vehicles"),
Item(name: "Wagon", category: "Vehicles")
]
func groupByCategory(_ items: [Item]) -> [(String, [Item])] {
let grouped = Dictionary(grouping: items, by: { $0.category })
return grouped.sorted(by: { $0.key < $1.key })
}
var body: some View {
List {
ForEach(groupByCategory(items), id: \.0) { pair in
Section(header: Text(pair.0)) {
ForEach(pair.1) { item in
Text(item.name)
}
}
}
}
}
}
struct GroupedList_Previews: PreviewProvider {
static var previews: some View {
GroupedList()
}
}
That’s it.