modemlooper avatar
About Blog

Customize List in SwiftUI

6 min read
swiftui

Customizing the appearance and behavior of Lists in SwiftUI is straightforward, though it can depend on the desired effect and the platform

Changing Row Content

The most common form of customization is providing custom content for each row, often using a combination of views like HStack, VStack, Text, and Image.

struct CustomRowView: View {
    let item: String
    
    var body: some View {
        HStack {
            Image(systemName: "star.fill") // Custom icon
                .foregroundColor(.yellow)
            VStack(alignment: .leading) {
                Text(item) // Main text
                    .font(.headline)
                Text("Detail for \(item)") // Detail text
                    .font(.subheadline)
                    .foregroundColor(.gray)
            }
            Spacer() // Pushes content to the left
            Text("New")
                .padding(5)
                .background(Color.blue)
                .foregroundColor(.white)
                .cornerRadius(5)
        }
    }
}

struct ContentView: View {
    let data = ["Apple", "Banana", "Cherry", "Date"]
    
    var body: some View {
        List {
            // Using the custom row view for each item
            ForEach(data, id: \.self) { item in
                CustomRowView(item: item)
            }
        }
    }
}

Adjusting Separators and Row Insets (iOS)

On iOS, you can hide the default row separators and manage insets.

  • Hiding Separators: You can apply the modifier listRowSeparator(.hidden) to the individual row content.
List {
    ForEach(data, id: \.self) { item in
        Text(item)
            .listRowSeparator(.hidden) // Hides the separator for this row
    }
}
// This style is often paired with setting the list style to .plain or .insetGrouped
  • Managing Insets: Use listRowInsets() to change the padding around the content of a row.
Text("A Wider Row")
    .listRowInsets(EdgeInsets(top: 10, leading: 50, bottom: 10, trailing: 50))

Changing the List Style

SwiftUI provides several built-in list styles that dramatically change the overall appearance, especially on iOS. Apply the .listStyle() modifier to the List.

StyleAppearance/BehaviorWhen to Use
.automaticDefault for the platform.General-purpose.
.plainRows extend edge-to-edge; headers/footers stick (iOS 15+).Simple, linear lists.
.groupedSections appear in distinct, rounded blocks.Settings, form-like data.
.insetGroupedSimilar to grouped, but inset from the screen edges.iOS standard for settings screens.
.sidebarDesigned for navigation/split views (iOS/iPadOS/macOS).Primary navigation lists.
List {
    Section("Fruit") {
        Text("Apple")
    }
}
.listStyle(.insetGrouped) // Applies the iOS "Settings" style

Swipes Actions and Context Menus

  1. Swipes Actions (Trailing/Leading)

You can add custom actions that appear when the user swipes a row (iOS 15+).

ForEach(data, id: \.self) { item in
    Text(item)
        .swipeActions(edge: .trailing) { // Define actions for swiping right-to-left
            Button("Archive") {
                // Archive logic
            }
            .tint(.orange)
            
            Button("Delete") {
                // Delete logic
            }
            .tint(.red)
        }
        .swipeActions(edge: .leading) { // Optional: for swiping left-to-right
            Button("Pin") {
                // Pin logic
            }
            .tint(.blue)
        }
}
  1. Context Menu (Long-Press)

Use the .contextMenu modifier to show a menu when a row is long-pressed (or right-clicked).

Text("Tap and Hold Me")
    .contextMenu {
        Button("Edit") { /* ... */ }
        Button("Share") { /* ... */ }
        Divider()
        Button("Delete", role: .destructive) { /* ... */ }
    }