30
Empty List placeholder. SwiftUI
Year twenty twenty-one. Almost a month has passed since the WWDC. As usual Apple presented many amazing features/updates 😍. As expected updated SwiftUI framework. But did not add placeholder for
List
view 😭. It's not big deal, but it was one of my expectations from conference. Okay let's do it ourselves 💪As an example, consider a simple list of countries. Show placeholder when data is empty.


Country model:
struct Country: Identifiable {
let id = UUID()
let name: String
}
So, have any ideas on how to implement a placeholder?
The first thing that comes to mind it's
if else
conditional statement.struct ContentView: View {
@State var countries: [Country] = [] // Data source
var body: some View {
if countries.isEmpty {
Text("No Countries") // Placeholder
.font(.largeTitle)
} else {
List(countries) { country in // List countires
Text(country.name)
.font(.title)
}
}
}
}
Advantages:
Disadvantages:
It works and sometimes it's enough. But in production, it would be nice to have a component that implements the logic of displaying a placeholder inside the component. So, goes to the next idea.
Improve
if else
idea and move logic show/hide placeholder to custom view, call it EmptyList
:struct EmptyList<Items: RandomAccessCollection, ListRowView: View, PlaceholderView: View>: View where Items.Element: Identifiable {
private let items: Items
private let listRowView: (Items.Element) -> ListRowView
private let placeholderView: () -> PlaceholderView
/// - Parameters:
/// - items: Source data for List. Item must implement Identifiable protocol
/// - listRowView: View displayed for each source Item
/// - placeholderView: Placeholder. View displayed when the items collection isEmpty
init(_ items: Items,
@ViewBuilder listRowView: @escaping (Items.Element) -> ListRowView,
@ViewBuilder placeholderView: @escaping () -> PlaceholderView) {
self.items = items
self.listRowView = listRowView
self.placeholderView = placeholderView
}
var body: some View {
if !items.isEmpty {
List { // List countires
ForEach(items) { item in
self.listRowView(item)
}
}
} else {
placeholderView()
}
}
}
Using the
EmptyList
is very easy. First parameter - data source, second parameter - list row view, and finally third parameter - placeholder view.struct ContentView: View {
@State var countries: [Country] = [] // Data source
var body: some View {
EmptyList(countries, // Data items
listRowView: { country in // List row view
Text(country.name)
.font(.title)
}, placeholderView: {
Text("No Countries") // Placeholder
.font(.largeTitle)
})
}
}
Advantages:
Disadvantages:
EmptyList
view, and if want to add some ViewModifier-s to the list, need for more efforts and modify codeUsually, I would have to say that this is all and say goodbye but is not all 😎. I want to share an idea of how I cook placeholder for lists in my projects.
struct EmptyDataModifier<Placeholder: View>: ViewModifier {
let items: [Any]
let placeholder: Placeholder
@ViewBuilder
func body(content: Content) -> some View {
if !items.isEmpty {
content
} else {
placeholder
}
}
}
Uses
EmptyDataModifier
:struct ContentView: View {
@State var countries: [Country] = [] // Data source
var body: some View {
List(countries) { country in
Text(country.name)
.font(.title)
}
.modifier(EmptyDataModifier(
items: countries,
placeholder: Text("No Countries").font(.title)) // Placeholder
)
}
}
That's it! Also via extension can little bit improve the solution and limited apply
EmptyDataModifier
only for List
.extension List {
func emptyListPlaceholder(_ items: [Any], _ placeholder: AnyView) -> some View {
modifier(EmptyDataModifier(items: items, placeholder: placeholder))
}
}
struct ContentView: View {
@State var countries: [Country] = [] // Data source
var body: some View {
List(countries) { country in
Text(country.name)
.font(.title)
}
.emptyListPlaceholder(
countries,
AnyView(ListPlaceholderView()) // Placeholder
)
}
}
Advantages:
List
viewDisadvantages:
In my opinion, the most suitable way to implement a placeholder is to use a custom
I'm sure sooner or later the Apple will add a placeholder for the List view. Maybe this article will be as a request for this feature for Apple. Who knows.
ViewModifier
. I'm sure sooner or later the Apple will add a placeholder for the List view. Maybe this article will be as a request for this feature for Apple. Who knows.
Thanks for reading! See you soon.
30