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.
• 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.
Empty search state
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:

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:

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:

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

