ContentUnavailableView Handle Empty States in SwiftUI

Handle empty states with the new SwiftUI ContentUnavailableView. Available for iOS 17, macOS 14, tvOS 17 and watchOS 10.

Francesco Leoni

2 min read

Availability

iOS 17

macOS 14

tvOS 17

watchOS 10

With iOS 17 Apple introduced in SwiftUI a new View to handle empty states or even errors.

It's called ContentUnavailableView, of course it's design it's very "Apple" but it has some degree of customisation.

Usage

ContentUnavailableView provides a ready-to-use configuration and inits to let you customise it.

This is a common scenarios for many apps and having a SwiftUI built-in View that can handle this case in nice.

ContentUnavailableView provides the search and search(text:) inits.

The first one will display a default message "No Results" while the second one "No Results for “User text“".

struct PostsListView: View {

  var posts: [Post]

  @State var searchResults: [Post] = []

  @State var searchText: String = ""

  var body: some View {

    NavigationStack {

      List(searchResults) { post in

        PostView(post: post)

      }

      .searchable(text: $searchText)

      .navigationTitle("Posts")

      .overlay {

        /// If the searchText is not empty and there are no searchResults, show the ContentUnavailableView.

        if !searchText.isEmpty, searchResults.isEmpty {

          ContentUnavailableView.search(text: searchText)

        }

      }

    }

  }

}

Here the relevant code is:

ContentUnavailableView.search(text: searchText)

The result will look as follows:

Search empty state

Unfortunately you can't change the description text. To do so you can create a custom ContentUnavailableView.

Generic empty state

Now, if you need a greater level of customisation, there are many inits that will let you do so.

Here is an example:

struct PostsListViewm: View {

  var posts: [Post]

  var body: some View {

    NavigationStack {

      List(posts) { post in

        PostView(post: post)

      }

      .navigationTitle("Posts")

      .overlay {

        if posts.isEmpty {

          ContentUnavailableView("No posts", systemImage: "doc.append", description: Text("Write your first post!"))

        }

      }

    }

  }

}

Here the relevant code is:

ContentUnavailableView("No posts", systemImage: "doc.append", description: Text("Write your first post!"))

The result will look as follows:

Generic empty state

Actions

With ContentUnavailableView you can suggest user what to do next.

ContentUnavailableView {

VStack {

Image(systemName: "doc.append")

.font(.system(size: 50))

.foregroundStyle(Color.secondary)

Text("No posts")

}

} description: {

Text("Write your first post!")

} actions: {

Text("Tap the “+“ button and start writing")

}

And the result will be:

Generic empty state with actions

Resources

Here is the Apple documentation about ContentUnavailableView.

Conclusion

ContentUnavailableView is a really nice addition to SwiftUI that can be used in many cases.

It allows you to customise it pretty well and provides a default implementation to handle empty search results.

If you have any question about this article, feel free to email me or tweet me @franceleonidev and share your opinion.

Thank you for reading and see you in the next article!

Share this article

Related articles


Combine CoreData and SwiftUI

See how to use CoreData database with SwiftUI. Syncing changes from CoreData to every View of your app.

5 min read

SwiftUICoreData

SwiftData the Successor of CoreData Explained with SwiftUI

Discover the SwiftData framework built on top of CoreData. Save and fetch data locally. Available for Xcode 15, Swift and SwiftUI.

5 min read

SwiftUICoreData

Make your Chart Scrollable with SwiftUI Charts (iOS 17)

Discover the new SwiftUI Charts APIs that enables you to create scrollable chart easily. Available for Xcode 15 and iOS 17.

2 min read

ChartsSwiftUI