Customizing List Row Separator Color in SwiftUI

Customizing List Row Separator Color in SwiftUI

At WWDC 21, Apple introduced many ways to visually customize the SwiftUI views. One of them was to be able to customize the color of row separators in the SwiftUI List. The new API offers a convenient way to customize its appearance.

Let's see how to use it with examples. We have an app that shows the collection of places in the list view. With each item, there is an associated text, icon, and theme color.


import SwiftUI

struct Place: Identifiable {
    let name: String
    let imageName: String
    let themeColor: Color

    var id: String {
        name
    }
}

struct ContentView: View {

    let places = [
        Place(name: "Mumbai", imageName: "car", themeColor: .red),
        Place(name: "Vienna", imageName: "airplane", themeColor: .green),
        Place(name: "Amsterdam", imageName: "camera", themeColor: .orange)
    ]

    var body: some View {
        List {
            ForEach(places) { place in
                HStack {
                    Image(systemName: place.imageName)
                    Text(place.name)
                }
            }
        }
    }
}

If we use the default list presentation, it will be shown like this with a default separator color without any customization.

The default separator color for SwiftUI lists is gray

Without Customization

However, let's say, a product manager comes to you and asks to modify it so that each separator gets the color associated with that place. In previous versions, we would have to create a horizontal divider and manually assign the individual color to it for every list item.

With Xcode 13.4 and iOS 15+, there is a new way to color individual separators. We can directly use listRowSeparatorTint API to color individual row separators in the list. In this case, we will use the color associated with each place in the given collection.

This is how the modified code looks like when list row separator tint is applied to each row item and is reflected in the app as shown below,

With Customization

💡
Please note that we cannot customize the colors of all separators with this API. We can only modify the colors of the separator associated with each list item. For example, listRowSeparatorTint is not applicable to the List object. It only applies to the SwiftUI view which represents individual items in the list. In this example, HStack which stores place icon and the title
As you can see the separator color for the last item is ignored. That's because there is no more list items to provide separation from. That means, in our case, we have needlessly provided the color for last item, but that's fine
Unfortunately, there is no API to customize row separator color with just one value. Either you go with default color or provide colors for each separators in the list

Bonus Content

Hiding List Row Separators

Too many separators could be distracting and can sway users away from the real purpose of the app.

As a part of clean and clear design concepts, you might altogether want to take the separators out. In the new edition of Xcode, Apple also provided a way to hide row separators. We can hide it by using .listRowSeparator(.hidden) view modifier on the view representing each list item.


List {
    ForEach(places) { place in
        HStack {
            Image(systemName: place.imageName)
            Text(place.name)
        }
        .listRowSeparator(.hidden)
    }
}

Demo

Summary

That's all for today, folks. Hope you liked the article. I will continue "The New APIs in Swift" series for the next few days and add a few more articles about new things introduced in SwiftUI in the past couple of years (WWDC21 and WWDC22). For any questions, feedback, comments,  or request for an article on the new topic, please reach out on Twitter @jayeshkawli