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.

What are you thoughts about this? Tweet me @franceleonidev and share your opinion.

Source link