One Logo Pool Ball
SwiftUI · IOS API REFERENCE

List

struct · iOS 13.0+ · SDK 27.1

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

A container that presents rows of data arranged in a single column, optionally providing the ability to select one or more members. In its simplest form, a `List` creates its contents statically, as shown in the following example: var body: some View { List { Text("A List Item") Text("A Second List Item") Text("A Third List Item") } } ![A vertical list with three text views.](List-1-iOS) More commonly, you create lists dynamically from an underlying collection of data. The following example shows how to create a simple list from an array of an `Ocean` type which conforms to <doc://com.apple.documentation/documentation/Swift/Identifiable>: struct Ocean: Identifiable { let name: String let id = UUID() } private var oceans = [ Ocean(name: "Pacific"), Ocean(name: "Atlantic"), Ocean(name: "Indian"), Ocean(name: "Southern"), Ocean(name: "Arctic") ] var body: some View { List(oceans) { Text($0.name) } } ![A vertical list with five text views, each with the name of an ocean.](List-2-iOS) ### Supporting selection in lists To make members of a list selectable, provide a binding to a selection variable. Binding to a single instance of the list data's `Identifiable.ID` type creates a single-selection list. Binding to a <doc://com.apple.documentation/documentation/Swift/Set> with a type that matches the list data's `Identifiable.ID` type creates a list that supports multiple selections. The following example shows how to add multiselect to the previous example: struct Ocean: Identifiable, Hashable { let name: String let id = UUID() } private var oceans = [ Ocean(name: "Pacific"), Ocean(name: "Atlantic"), Ocean(name: "Indian"), Ocean(name: "Southern"), Ocean(name: "Arctic") ] @State private var multiSelection = Set<UUID>() var body: some View { NavigationView { List(oceans, selection: $multiSelection) { Text($0.name) } .navigationTitle("Oceans") .toolbar { EditButton() } } Text("\(multiSelection.count) selections") } When people make a single selection by tapping or clicking, the selected cell changes its appearance to indicate the selection. To enable multiple selections with tap gestures, put the list into edit mode by either modifying the ``EnvironmentValues/editMode`` value, or adding an ``EditButton`` to your app's interface. When you put the list into edit mode, the list shows a circle next to each list item. The circle contains a checkmark when the user selects the associated item. The example above uses an Edit button, which changes its title to Done while in edit mode: ![A navigation view with the title Oceans and a vertical list that contains five text views, each with the name of an ocean. The second and third items are highlighted to indicate that they are selected. At the bottom, a text view reads 2 selections.](List-3-iOS) People can make multiple selections without needing to enter edit mode on devices that have a keyboard and mouse or trackpad, like Mac and iPad. ### Refreshing the list content To make the content of the list refreshable using the standard refresh control, use the ``View/refreshable(action:)`` modifier. The following example shows how to add a standard refresh control to a list. When the user drags the top of the list downward, SwiftUI reveals the refresh control and executes the specified action. Use an `await` expression inside the `action` closure to refresh your data. The refresh indicator remains visible for the duration of the awaited operation. struct Ocean: Identifiable, Hashable { let name: String let id = UUID() let stats: [String: String] } class OceanStore: ObservableObject { @Published var oceans = [Ocean]() func loadStats() async {} } @EnvironmentObject var store: OceanStore var body: some View { NavigationView { List(store.oceans) { ocean in HStack { Text(ocean.name) StatsSummary(stats: ocean.stats) // A custom view for showing statistics. } } .refreshable { await store.loadStats() } .navigationTitle("Oceans") } } ### Supporting multidimensional lists To create two-dimensional lists, group items inside ``Section`` instances. The following example creates sections named after the world's oceans, each of which has ``Text`` views named for major seas attached to those oceans. The example also allows for selection of a single list item, identified by the `id` of the example's `Sea` type. struct ContentView: View { struct Sea: Hashable, Identifiable { let name: String let id = UUID() } struct OceanRegion: Identifiable { let name: String let seas: [Sea] let id = UUID() } private let oceanRegions: [OceanRegion] = [ OceanRegion(name: "Pacific", seas: [Sea(name: "Australasian Mediterranean"), Sea(name: "Philippine"), Sea(name: "Coral"), Sea(name: "South China")]), OceanRegion(name: "Atlantic", seas: [Sea(name: "American Mediterranean"), Sea(name: "Sargasso"), Sea(name: "Caribbean")]), OceanRegion(name: "Indian", seas: [Sea(name: "Bay of Bengal")]), OceanRegion(name: "Southern", seas: [Sea(name: "Weddell")]), OceanRegion(name: "Arctic", seas: [Sea(name: "Greenland")]) ] @State private var singleSelection: UUID? var body: some View { NavigationView { List(selection: $singleSelection) { ForEach(oceanRegions) { region in Section(header: Text("Major \(region.name) Ocean Seas")) { ForEach(region.seas) { sea in Text(sea.name) } } } } .navigationTitle("Oceans and Seas") } } } Because this example uses single selection, people can make selections outside of edit mode on all platforms. ![A vertical list split into sections titled Major Pacific Ocean Seas, Major Atlantic Ocean Seas, and so on. Each section has a different number of rows, with the names of various seas. Within the Major Atlantic Ocean Seas section, the row Sargasso is selected.](List-4-iOS) > Note: In iOS 15, iPadOS 15, and tvOS 15 and earlier, lists support selection only in edit mode, even for single selections. ### Creating hierarchical lists You can also create a hierarchical list of arbitrary depth by providing tree-structured data and a `children` parameter that provides a key path to get the child nodes at any level. The following example uses a deeply-nested collection of a custom `FileItem` type to simulate the contents of a file system. The list created from this data uses collapsing cells to allow the user to navigate the tree structure. struct ContentView: View { struct FileItem: Hashable, Identifiable, CustomStringConvertible { var id: Self { self } var name: String var children: [FileItem]? = nil var description: String { switch children { case nil: return "📄 \(name)" case .some(let children): return children.isEmpty ? "📂 \(name)" : "📁 \(name)" } } } let fileHierarchyData: [FileItem] = [ FileItem(name: "users", children: [FileItem(name: "user1234", children: [FileItem(name: "Photos", children: [FileItem(name: "photo001.jpg"), FileItem(name: "photo002.jpg")]), FileItem(name: "Movies", children: [FileItem(name: "movie001.mp4")]), FileItem(name: "Documents", children: []) ]), FileItem(name: "newuser", children: [FileItem(name: "Documents", children: []) ]) ]), FileItem(name: "private", children: nil) ] var body: some View { List(fileHierarchyData, children: \.children) { item in Text(item.description) } } } ![A list providing an expanded view of a tree structure. Some rows have a chevron on the right to indicate that they have child rows. The chevron points right when the row's child rows are hidden and points down when they are visible. Row content that is slightly indented from the content in the previous row indicates that the row is a child of the row above. The first three rows, titled users, user1234, and Photos, have downward facing chevrons and are progressively indented. The next two rows, indented together from Photos and titled photo001.jpg and photo002.jpg, have no chevron. The next two rows, titled Movies and Documents have right facing chevrons and align with the Photos row. The next row, titled newuser, has a right facing chevron and is aligned with user1234. The last row is titled private, has no chevron, and is aligned with users.](List-5-iOS) ### Styling lists SwiftUI chooses a display style for a list based on the platform and the view type in which it appears. Use the ``View/listStyle(_:)`` modifier to apply a different ``ListStyle`` to all lists within a view. For example, adding `.listStyle(.plain)` to the example shown in the "Creating Multidimensional Lists" topic applies the ``ListStyle/plain`` style, the following screenshot shows: ![A vertical list split into sections titled Major Pacific Ocean Seas, Major Atlantic Ocean Seas, etc. Each section has a different number of rows, with the names of various seas. Within the Major Atlantic Ocean Seas section, the row Sargasso is selected.](List-6-iOS)

Members (0)

This type has no directly callable members in this snapshot. See the framework’s skipped declarations for unsupported APIs.

Skipped declarations

37 declarations were excluded from these bindings. Each reason comes from the generator or the iOS SDK compiler.

List.init(selection:content:)

callback cannot propagate synchronous failure

List.init(selection:content:)

callback cannot propagate synchronous failure

List.body

This protocol needs associated types that cannot yet cross the bridge.

List.init(_:selection:rowContent:)

This declaration needs Swift generic type arguments. (no canonical witness for Data)

List.init(_:children:selection:rowContent:)

This declaration needs Swift generic type arguments. (no canonical witness for Data)

List.init(_:id:selection:rowContent:)

This declaration needs Swift generic type arguments. (no canonical witness for Data)

List.init(_:id:children:selection:rowContent:)

This declaration needs Swift generic type arguments. (no canonical witness for Data)

List.init(_:selection:rowContent:)

callback cannot propagate synchronous failure

List.init(_:selection:rowContent:)

This declaration needs Swift generic type arguments. (no canonical witness for Data)

List.init(_:children:selection:rowContent:)

This declaration needs Swift generic type arguments. (no canonical witness for Data)

List.init(_:id:selection:rowContent:)

This declaration needs Swift generic type arguments. (no canonical witness for Data)

List.init(_:id:children:selection:rowContent:)

This declaration needs Swift generic type arguments. (no canonical witness for Data)

List.init(_:selection:rowContent:)

callback cannot propagate synchronous failure

List.init(content:)

callback cannot propagate synchronous failure

List.init(_:rowContent:)

This declaration needs Swift generic type arguments. (no canonical witness for Data)

List.init(_:children:rowContent:)

This declaration needs Swift generic type arguments. (no canonical witness for Data)

List.init(_:id:rowContent:)

This declaration needs Swift generic type arguments. (no canonical witness for Data)

List.init(_:id:children:rowContent:)

This declaration needs Swift generic type arguments. (no canonical witness for Data)

List.init(_:rowContent:)

callback cannot propagate synchronous failure

List.init(_:selection:rowContent:)

This declaration needs Swift generic type arguments. (no canonical witness for Data)

List.init(_:id:selection:rowContent:)

This declaration needs Swift generic type arguments. (no canonical witness for Data)

List.init(_:selection:rowContent:)

This declaration needs Swift generic type arguments. (no canonical witness for Data)

List.init(_:id:selection:rowContent:)

This declaration needs Swift generic type arguments. (no canonical witness for Data)

List.init(_:rowContent:)

This declaration needs Swift generic type arguments. (no canonical witness for Data)

List.init(_:id:rowContent:)

This declaration needs Swift generic type arguments. (no canonical witness for Data)

List.init(_:children:selection:rowContent:)

This declaration needs Swift generic type arguments. (no canonical witness for Data)

List.init(_:id:children:selection:rowContent:)

This declaration needs Swift generic type arguments. (no canonical witness for Data)

List.init(_:children:selection:rowContent:)

This declaration needs Swift generic type arguments. (no canonical witness for Data)

List.init(_:id:children:selection:rowContent:)

This declaration needs Swift generic type arguments. (no canonical witness for Data)

List.init(_:children:rowContent:)

This declaration needs Swift generic type arguments. (no canonical witness for Data)

All SwiftUI types →