How to color the background of a ForEach nested inside a List with a plain style

Written by
Rob Bentley

Originally Published on November 15, 2022
Republished on June 5, 2023

I recently was facing an issue where I wanted to nest a ForEach in a List. I needed to use List instead of a simple ForEach because I wanted to have the swipe to delete feature.

The problem was that the background of the ForEach was defaulting to the SystemBackgroundColor, and I wanted it to be the same color as my ForEach Content Body.

When I would use a simple ForEach, the background color was easily set by using:

{ .background(Color.white) }

When I nested the ForEach inside the List, the background color was still fine, until iOS 16 came out.

After a bit of digging (and trial and error), I found the solution for actually being able to set the background color of a List set to PlainListStyle.

A ViewModifier needed to be set for iOS 16 and above, to make the scrollContentBackground hidden. Once this was in place, the list respected the set background color.

Here is the full code sample:

struct ContentView: View {
    @State var abcArray = ["A", "B", "C", "D", "E", "F", "G"]
    var body: some View {
        ZStack {
            Color.white
                list
                    .padding(.top, 60)
        }
        .ignoresSafeArea()
    }
    var list: some View {
        List {
            ForEach(abcArray, id: \.self) { result in
                HStack {
                    Text(result)
                        .frame(height: 40)
                        .foregroundColor(.black)
                    Spacer()
                    Image(systemName: "chevron.right")
                        .font(Font.system(size: 13, weight: .semibold, design: .default))
                        .foregroundColor(Color(red: 0.771, green: 0.771, blue: 0.779))
                }.padding(.horizontal, 20)
                    .background(Color.white)
                    .onTapGesture {
                        // Do Something
                    }
                    .listRowInsets(EdgeInsets())
                    .listRowBackground(Color.white)
            }
            .onDelete(perform: deleteSomething(at:))
        }
        .listStyle(PlainListStyle())
        .modifier(ListBackgroundModifier())
    }
    func deleteSomething(at offsets: IndexSet) {
        //Delete Something
    }
}

struct ListBackgroundModifier: ViewModifier {
    @ViewBuilder
    func body(content: Content) -> some View {
        if #available(iOS 16.0, *) {
            content
                .scrollContentBackground(.hidden)
        } else {
            content
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Robert Bentley is a self-taught developer who's been building mobile software for over ten years. As the CEO of JMG each project, platform update, and emerging tech integration brings something new to learn, and he shares these short tips in hopes they help someone else doing something for the first time. To learn more about Rob, connect with him on LinkedIn.

Join our newsletter community

Oh no, there was an error with your email!

Hey, thank you so much for signing up! We've got your address saved, so look forward to an email from us soon. 🎉

We respect your privacy.