Search code examples
swiftlistswiftui

SwiftUI: List background is black when it is an empty List


My List looks like this:

List(viewModel.exerciseSelection, id: \.id) { exercise in
    AddWorkoutDetailView(exerciseName: exercise.name, gifImage: exercise.gifUrl)
        .listRowInsets(EdgeInsets())
        .listRowBackground(Color.backgroundColor)
        .swipeActions(allowsFullSwipe: false) {
            Button(role: .destructive) {
                                
            } label: {
                Label("Delete", systemImage: "trash.fill")
            }
        }
}
.listStyle(.plain)
.scrollContentBackground(.hidden)
.listRowBackground(Color.backgroundColor)

EDIT: My whole View is structured like this:

NavigationStack { 
    ZStack {
        Color.backgroundColor
            .ignoresSafeArea()

        VStack {
            // some other stuff
            List {
                // my list from above
            }
        }
    }
}

The Problem is, that when my List is empty, there will be a black background and not my custom background color, which is present when the List is populated.

Empty List

Populated List


Solution

  • It seems like a Bug in SwiftUI but first of all:

    You are using listRowBackground modifier instead of background on the List and there is no Row to background! change it to background.

    List(viewModel.exerciseSelection, id: \.id) { exercise in
       ,,,
    }
    .listStyle(.plain)
    .scrollContentBackground(.hidden)
    .background(Color.backgroundColor) // 👈 1 absolute issue was here
    

    and then You can either fallback to the UIScrollView:

    init() {
        UIScrollView.appearance().backgroundColor = .clear
    }
    

    2.

    Or hide the entire List by the opacity modifier to prevent branching and layout issues and unnecessary re-rendering like this:

    List(...) { ... }
    .opacity(viewModel.exerciseSelection.isEmpty ? 0 : 1)
    

    3.

    Or you can use LazyVStack instead:

    ScrollView {
        LazyVStack {
            ForEach(viewModel.exerciseSelection, id: \.self) { exercise in ... }
        }
    }