跳转至
Structure

List

A scrollable list of data.

Declaration

struct List<SelectionValue, Content> : View where SelectionValue : Hashable, Content : View

Overview

List is a view that represents a scrollable list of data.

Creating a List with a fixed number of elements

The following creates a List with three rows of text:

struct ExampleView: View {
    var body: some View {
        List {
            Text("Bananas 🍌🍌")
            Text("Apples 🍏🍏")
            Text("Peaches 🍑🍑")
        }
    }
}
A view displaying a list containing three text members, "Bananas 🍌🍌", "Apples 🍏🍏", and "Peaches 🍑🍑".

Creating a List with a variable number of elements

In the following example, init(_:id:rowContent:) is used to dynamically create a List over an array of strings, fruits.

struct ExampleView: View {
    @State var fruits: [String] = ["Bananas 🍌🍌", "Apples 🍏🍏", "Peaches 🍑🍑"]

    var body: some View {
        List.init(fruits, id: \.self) { (fruit: String) in
            Text(fruit)
        }
    }
}
A view displaying a dynamic list containing an array with three string members, "Bananas 🍌🍌", "Apples 🍏🍏", and "Peaches 🍑🍑," each displayed as a separate list item.

This is different from the previous example, because this initializer accepts a rowContent parameter that allows the List to generate SwiftUI views for the list's rows on-demand.

The id parameter requires a key-path to the identifier for each row of the List. This is required so that List can efficiently process changes in the data source (in this example, the array fruits). These changes to the data source are animated as insertions, removals and reorders - reflecting the changes in the source.

It is up to the programmer to decide what property best represents the 'identiifer' of a particular type. In this example, the String itself is a valid identifier for the data, therefore \.self is passed along to the id parameter.

Creating a List with both fixed and dynamic elements

List allows you to mix both fixed and dynamic elements using ForEach.

The following example displays a List of a fixed element ("Hello, World!") followed by dynamic elements from the previous example (using the fruits array):

struct ExampleView: View {
    @State var fruits: [String] = ["Bananas 🍌🍌", "Apples 🍏🍏", "Peaches 🍑🍑"]

    var body: some View {
        List {
            Text("Hello, World!")

            ForEach(fruits, id: \.self) { (fruit: String) in
                Text(fruit)
            }
        }
    }
}
A view displaying a list containing a fixed element "Hello, World!" and three dynamic elements, "Bananas 🍌🍌", "Apples 🍏🍏", and "Peaches 🍑🍑".

As seen in the above example, ForEach also accepts an id parameter along with a rowContent.

Adding sections to a List

The following example demonstrates the usage of Section.

struct ExampleView: View {
    @State var fruits: [String] = ["Bananas 🍌🍌", "Apples 🍏🍏", "Peaches 🍑🍑"]

    var body: some View {
        List {
            Section(header: Text("Not a fruit")) {
                Text("Hello, World!")
            }

            Section(header: Text("Fruit")) {
                ForEach(fruits, id: \.self) { (fruit: String) in
                    Text(fruit)
                }
            }
        }
    }
}
A view displaying a list separated into two sections, one with the header "NOT A FRUIT" above the element "Hello, World!" and another with the header "FRUIT" above three dynamic elements, "Bananas 🍌🍌", "Apples 🍏🍏", and "Peaches 🍑🍑".

A Section used within a List will render as a table-section containing the elements wrapped by that section. Just as for unsectioned elements, sections can hold both fixed and dynamic elements.

Styling a List

A List can be styled using the listStyle(_:) modifier.

The following example demonstrates how to style a List using the grouped-inset style:

struct ExampleView: View {
    var body: some View {
        List {
            Text("Bananas 🍌🍌")
            Text("Apples 🍏🍏")
            Text("Peaches 🍑🍑")
        }
        .listStyle(InsetGroupedListStyle())
    }
}
A view displaying a grouped-inset list containing three text members, "Bananas 🍌🍌", "Apples 🍏🍏", and "Peaches 🍑🍑".

SwiftUI offers various list styles:

Setting the background view for a list row

Use listRowBackground(_:) to set the background view for a given row.

The following example demonstrates how listRowBackground(_:) can be used to provide specific background colors for a list's rows:

struct ExampleView: View {
    var body: some View {
        List {
            Text("Bananas 🍌🍌")
                .listRowBackground(Color.yellow)
            Text("Apples 🍏🍏")
                .listRowBackground(Color.green)
            Text("Peaches 🍑🍑")
                .listRowBackground(Color.orange)
        }
    }
}
A view displaying a list containing three text members, "Bananas 🍌🍌", "Apples 🍏🍏", and "Peaches 🍑🍑", each with a different list row background color.

A background can be provided for multiple list rows at a time, by applying the listRowBackground(_:) modifier to ForEach.

In the following example, all the rows of the List have the background view Color.yellow.

struct ExampleView: View {
    @State var fruits: [String] = ["Bananas 🍌🍌", "Apples 🍏🍏", "Peaches 🍑🍑"]

    var body: some View {
        List {
            ForEach(fruits, id: \.self) { (fruit: String) in
                Text(fruit)
            }
            .listRowBackground(Color.yellow)
        }
    }
}
A view displaying a dynamic list containing an array with three string members, "Bananas 🍌🍌", "Apples 🍏🍏", and "Peaches 🍑🍑," each displayed as a separate list item with a yellow list row background.

Making list rows deletable

Apply the onDelete(perform:) modifier on a ForEach within a List to allow the list rows to become deletable.

struct ExampleView: View {
    @State var fruits = ["🍌", "🍏", "🍑"]

    var body: some View {
        NavigationView {
            List {
                ForEach(fruits, id: \.self) { fruit in
                    Text(fruit)
                }
                .onDelete { offsets in
                    fruits.remove(atOffsets: offsets)
                }
            }
            .toolbar {
                EditButton()
            }
        }
    }
}
A view displaying a list containing an array with three string members, "🍌", "🍏", and "🍑," each displayed as a separate deletable list item. The gif shows the "🍏" being deleted by sliding the row to the right and clicking the red "Delete" button that appears.

Editing a List using EditButton

An EditButton placed in the navigation bar of a NavigationView with a List in it can be used to provide an edit button for the List.

struct ExampleView: View {
    @State var fruits = ["🍌", "🍏", "🍑"]

    var body: some View {
        NavigationView {
            List {
                ForEach(fruits, id: \.self) { fruit in
                    Text(fruit)
                }
                .onDelete { offets in
                    fruits.remove(atOffsets: offets)
                }
            }
            .toolbar {
                EditButton()
            }
        }
    }
}
A gif showing a view with an "Edit" button right aligned above a list containg three fruit emojis as members; when clicked, the word "Edit" is replaced by "Done" and red "Delete" button appears in line with any list item when it is slid to the left.

Further notes

Although List is very powerful, it currently has some limitations:

  • The separator of a List cannot be removed.
  • SidebarListStyle is broken on macCatalyst.

Availability

iOS 13.0+

macOS 10.15+

tvOS 13.0+

watchOS 6.0+

Topics


Type Alias

Body The type of view representing the body of this view.


Instance Property

body The content of the list.


Initializer

init(_:children:rowContent:) Creates a hierarchical list that computes its rows on demand from an underlying collection of identifiable data.

init(_:children:selection:rowContent:) Creates a hierarchical list that computes its rows on demand from an underlying collection of identifiable data, optionally allowing users to select a single row.

init(_:children:selection:rowContent:) Creates a hierarchical list that computes its rows on demand from an underlying collection of identifiable data, optionally allowing users to select multiple rows.

init(_:id:children:rowContent:) Creates a hierarchical list that identifies its rows based on a key path to the identifier of the underlying data.

init(_:id:children:selection:rowContent:) Creates a hierarchical list that identifies its rows based on a key path to the identifier of the underlying data, optionally allowing users to select multiple rows.

init(_:id:children:selection:rowContent:) Creates a hierarchical list that identifies its rows based on a key path to the identifier of the underlying data, optionally allowing users to select a single row.

init(_:id:rowContent:) Creates a list that identifies its rows based on a key path to the identifier of the underlying data.

init(_:id:selection:rowContent:) Creates a list that identifies its rows based on a key path to the identifier of the underlying data, optionally allowing users to select multiple rows.

init(_:id:selection:rowContent:) Creates a list that identifies its rows based on a key path to the identifier of the underlying data, optionally allowing users to select a single row.

init(_:rowContent:) Creates a list that computes its views on demand over a constant range.

init(_:rowContent:) Creates a list that computes its rows on demand from an underlying collection of identifiable data.

init(_:selection:rowContent:) Creates a list that computes its rows on demand from an underlying collection of identifiable data, optionally allowing users to select a single row.

init(_:selection:rowContent:) Creates a list that computes its views on demand over a constant range.

init(_:selection:rowContent:) Creates a list that computes its views on demand over a constant range.

init(_:selection:rowContent:) Creates a list that computes its rows on demand from an underlying collection of identifiable data, optionally allowing users to select multiple rows.

init(content:) Creates a list with the given content.

init(selection:content:) Creates a list with the given content that supports selecting a single row.

init(selection:content:) Creates a list with the given content that supports selecting multiple rows.