2

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

bennyyy999
  • 80
  • 1
  • 5

3 Answers3

1

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 ... }
    }
}
Mojtaba Hosseini
  • 95,414
  • 31
  • 268
  • 278
  • Okay so your second option is my prefered one then, because I need the List for swipeOptions. Just saw the link on your comment to one of your posts and will watch the WWDC video, thanks for the tip, didn't know this would make a difference. I guess I will mark this as the solution. – bennyyy999 May 09 '23 at 21:26
  • You are free to choose but **note that** `List`s has some extra features like `swipeActions` that stacks don't and may require you to rearrange your layout because of `listRowBackground` and default layouts. – Mojtaba Hosseini May 09 '23 at 21:31
-1

If this happens to you, I just found that using an if-else statement can help. like so:

if list.isEmpty {
    Spacer() // needed in my case, because the View is only a VStack and not a ScrollView
} else {
    List {
    // content
    }
}

but still, there should be somehow an option to have a background without the need to check if a List is empty. Does someone know how?

bennyyy999
  • 80
  • 1
  • 5
-1

Don't ask why, but if you wrap all into a NavigationView it works:

struct ContentView: View {
    
    @State private var workouts: [String] = []
    
    var body: some View {
        NavigationView {
            VStack {
                Button("Add") {
                    workouts.append("exercise \(workouts.count)")
                }
                
                List(workouts, id: \.self) { exercise in
                    Text(exercise)
                        .listRowBackground(Color.clear)
                }
                .listStyle(.plain)
            }
            .padding()
            .background(.gray)
        }
    }
}
ChrisR
  • 9,523
  • 1
  • 8
  • 26