28
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.
28