I am using a ListView in Mac OS. I am trying to change that background color of that ListView. However, it is not that easy as expected.
I tried using .background(Color(.red))
attribute on the ListView. That didn't change anything.
I could only find .listRowBackground(Color(.red))
which had an influence on the table rows. However, the other background wasn't effected.
I prepared a little demo to demonstrate:
In my view body:
VStack
{
List()
{
Text("Test")
.listRowBackground(Color.green)
Text("Test")
.listRowBackground(Color.green)
Text("Test")
.listRowBackground(Color.green)
}.background(Color(.red))
}.background(Color(.red))
That is the result I get:
The main background does not change. I read about a solution changing the UITableView.appearance
but that is not possible for me in SwiftUI for Mac OS.
Thanks in advance
We can change the background color of a list row in SwiftUI with listRowBackground(_:) modifier. To set a list row background color, add listRowBackground(_:) modifier to the list row item.
Head to the same settings panel: System Preferences > Desktop & Screen Saver > Desktop. Under Apple on the left, click Colors. You'll see an assortment of solid colors, as well as a Custom Color button. Click to pick a color or hit the Custom button to create your own.
SwiftUI doesn't have a dedicated modifier for displaying background colors or images, but instead lets us specify any kind of background view using its background() modifier. To be clear, you can use any view as your background – another text view if you wanted, for example.
Update: I found a much better way to remove a list's background without affecting the whole app: by using Introspect.
import Introspect
import SwiftUI
extension List {
/// List on macOS uses an opaque background with no option for
/// removing/changing it. listRowBackground() doesn't work either.
/// This workaround works because List is backed by NSTableView.
func removeBackground() -> some View {
return introspectTableView { tableView in
tableView.backgroundColor = .clear
tableView.enclosingScrollView!.drawsBackground = false
}
}
}
Usage:
List {
ForEach(items) { item in
...
}
}.removeBackground()
Old answer:
@Asperi's answer works, but only until the window is resized. Here's another workaround for overriding List
's color:
extension NSTableView {
open override func viewDidMoveToWindow() {
super.viewDidMoveToWindow()
backgroundColor = NSColor.clear
enclosingScrollView!.drawsBackground = false
}
}
A potential downside is that this will affect all lists in the app.
Unfortunately, ListStyle
protocol is not documented and .listStyle
modifier has very limited usage, you can choose from CarouselListStyle, DefaultListStyle, GroupedListStyle ,PlainListStyle, SidebarListStyle
Try to mimic List with ScrollView combined with ForEach, which gives you a lot of flexibility, the missing parts are easy to write. Once the ListStyle will be available for developers, it will be easy to change the code ...
Example with source code
struct ContentView: View {
var body: some View {
HStack(spacing: 0) {
ScrollView {
ForEach(0 ..< 4) { idx in
VStack(alignment: .leading) {
Divider().background(Color.blue)
Text("Test \(idx)")
.padding(.horizontal, 10)
.background(Color.pink)
//Divider()
}.padding(.bottom, -6)
}
}
.frame(maxWidth: 100)
.background(Color.gray)
Color.green
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With