TechnologiesSwiftUI

ContentUnavailableView struct

iOSmacOStvOSwatchOSvisionOSiOS 17.0+✓ renders

An interface, consisting of a label and additional content, that you

How it works

ContentUnavailableView is a SwiftUI view that presents a standardized empty state: the screen people see when there's no content to show, such as an inbox with no mail, search results that came back empty, or a list waiting on its first item. It gives these moments a consistent, platform-native appearance with a prominent icon, a title, optional explanatory text, and optional call-to-action controls, so you don't have to hand-assemble a stack of Image, Text, and Button views every time. Reach for it wherever a view would otherwise render nothing, and conditionally show it in place of your real content while that content is missing.

  1. Provide the label with a trailing closure

    The primary initializer takes a label view builder that supplies the emphasized headline at the center of the empty state. A Label is the natural fit here because it pairs title text with an SF Symbol; in the example the label reads Label("No Mail", systemImage: "tray.fill"), which ContentUnavailableView styles automatically with the large, dimmed icon-over-title treatment.

  2. Explain the situation with the description closure

    The description parameter is a second view builder for the secondary line beneath the title, where you tell people why the view is empty and what to expect. Keep it to a short sentence of Text, as in Text("New messages you receive will appear here."). It's optional — omit the closure when the label alone is self-explanatory.

  3. Offer next steps with the actions closure

    The actions view builder hosts controls that let people move forward — retry, reload, create the first item, or adjust a filter. Here Button("Refresh") {} carries .buttonStyle(.borderedProminent) so it reads as the primary action. ContentUnavailableView arranges whatever buttons you place in this closure below the description, and you can leave it out entirely for a purely informational state.

  4. Use the search preset for empty results

    Beyond the label/description/actions form, ContentUnavailableView provides a built-in ContentUnavailableView.search configuration (and a search(text:) variant) for the common case of a query that returned nothing. It renders the system's standard "no results" presentation, so you get the same magnifying-glass icon and copy users see across the OS without writing your own label.

  5. Apply layout and styling modifiers like any view

    ContentUnavailableView conforms to View, so the whole composition participates in the normal modifier chain. In the example a single .padding() insets the entire empty state; you'd typically drop the view into a branch of your layout — swapping it in for your list or grid while the data is absent — and let its centered content fill the available space.

Try it — Delete the actions: closure containing Button("Refresh") and watch ContentUnavailableView collapse to just the title and description, showing how it adapts to a purely informational empty state.

Example & preview

Press Run live & edit to compile it in your browser — then edit the Swift on the left and the preview re-renders live.

ContentUnavailableView.swift
struct ContentUnavailableViewDemo: View {
    var body: some View {
        ContentUnavailableView {
            Label("No Mail", systemImage: "tray.fill")
        } description: {
            Text("New messages you receive will appear here.")
        } actions: {
            Button("Refresh") {}
                .buttonStyle(.borderedProminent)
        }
        .padding()
    }
}
Live preview
No Results
No Results
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →