16

I am trying on setting a view background color to black with the following code

struct RuleList: View {[![enter image description here][1]][1]
private var presenter: ConfigurationPresenter?

@ObservedObject
private var viewModel: RowListViewModel

init(presenter: ConfigurationPresenter?, viewModel: RowListViewModel) {
    self.presenter = presenter
    self.viewModel = viewModel
}

var body: some View {
    List(viewModel.configurations) { configuration in
        RuleListRow(website: configuration.website).background(Color.black)
    }.background(Color.black)
}
}

struct RuleListRow: View {
var website: Website
@State private var websiteState = 0

var body: some View {
    VStack {
        Text(website.id).foregroundColor(.white)

        Picker(website.id, selection: $websiteState) {
            Text("Permis").tag(0)
            Text("Ascuns").tag(1)
            Text("Blocat").tag(2)
        }.pickerStyle(SegmentedPickerStyle()).background(Color.crimson)
    }.listRowBackground(Color.green)
}
}

The view is hosted in a mixed UIKit - SwiftUI storyboard, so this specific view is embed in a Hosting controller

class ConfigurationHostingController: UIHostingController<RuleList> {
private var presenter: ConfigurationPresenter = ConfigurationPresenter()

required init?(coder: NSCoder) {
    super.init(rootView: RuleList(presenter: presenter, viewModel: presenter.rowListViewModel))
}
}

I've tried any combination of .background, .listRowBackground(Color.black) and .colorMultiply(.black) I could think of, and the best I got is this

issue

trusk
  • 1,634
  • 2
  • 18
  • 32

1 Answers1

56

iOS 16

Since Xcode 14 beta 3, You can change the background of all lists and scrollable contents using this modifier:

.scrollContentBackground(.hidden)

You can pass in .hidden to make it transparent. So you can see the color or image underneath.


iOS 14

In iOS 14, you may consider using LazyVStack instead of list for this:

ScrollView {
    LazyVStack {
        ForEach((1...100), id: \.self) {
            Text("Placeholder \($0)")
        }
    }
    .background(Color.yellow)
}

Keep in mind that LazyVStack is lazy and doesn't render all rows all the time. So they are very performant and suggested by Apple itself in WWDC 2020.


iOS 13

All SwiftUI's Lists are backed by a UITableViewin iOS. so you need to change the background color of the tableView. But since Color and UIColor values are slightly different, you can get rid of the UIColor.

struct ContentView: View {
    
    init() {
        /// These could be anywhere before the list has loaded.
        UITableView.appearance().backgroundColor = .clear // tableview background
        UITableViewCell.appearance().backgroundColor = .clear // cell background
    }

    var body: some View {
        List {
            ,,,
        }
        .background(Color.yellow)
    }
}

Now you can use Any background (including all Colors) you want

Note that those top and bottom white areas are safe are and you can use .edgesIgnoringSafeArea() modifier to get rid of them.

⚠️ Important note!

Apple is on its way to deprecate all UIKit tricks that we are using in the SwiftUI (like tweaking the UIAppearance). So you may want to consider adapting your code to the latest iOS always

Mojtaba Hosseini
  • 95,414
  • 31
  • 268
  • 278
  • 2
    That was it. I've tried setting it for just the table, but apparently also needed for the cell. – trusk Oct 28 '19 at 13:48
  • I’ve noticed that this also changes the colours of any subsequent views. For example from my list I am opening a sheet and the colours are all changed. Is there a way to make this work for a single view or reset it on other views? – ponens Jan 13 '20 at 12:53
  • Yes, using `onAppear` modifier instead of `init` – Mojtaba Hosseini Jan 13 '20 at 16:01
  • @MojtabaHosseini putting it on `onAppear` causes my other tables to still have the clear behavior. what else can i do? – fphelp Aug 29 '20 at 03:46
  • contentView of cell is still black with this approach. So you will need smth like ' UIView.appearance().backgroundColor = .white' lol – protspace Sep 28 '20 at 15:10
  • I would put the UITableView appearance code in the `App` initializer since this globally affects all the table views. But this is nitpicking. The bigger issue here is, that the `UITableViewCell.appearance().backgroundColor` doesn't actually set the cells background color - since there is another system provided view in the back of the cell, which colour is white (light mode) / black (dark mode) and will not be affected by the appearance (bug?). So far, it seems we have to stick with the default (yikes), till the Maker provides a better solution for us - or go with LazyVStack and skip iOS 13. – CouchDeveloper May 04 '21 at 12:17