我在Mac OS中使用ListView。我试图更改该ListView的背景颜色。但是,这并不像预期的那么容易。
我尝试在ListView上使用.background(Color(.red))
属性。那什么都没改变。
我只能找到对表行有影响的.listRowBackground(Color(.red))
。但是,其他背景没有受到影响。
我准备了一个小演示来演示:
在我看来:
VStack
{
List()
{
Text("Test")
.listRowBackground(Color.green)
Text("Test")
.listRowBackground(Color.green)
Text("Test")
.listRowBackground(Color.green)
}.background(Color(.red))
}.background(Color(.red))
那是我得到的结果:
主要背景不变。我读到有关更改UITableView.appearance
的解决方案的信息,但对于Mac OS的SwiftUI,这对我来说是不可能的。
预先感谢
答案 0 :(得分:7)
更新:我找到了一种更好的方法来删除列表背景,而又不影响整个应用程序:使用Introspect。
import Introspect
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
}
}
}
用法:
List {
ForEach(items) { item in
...
}
}.removeBackground()
旧答案:
@Asperi's answer有效,但仅在调整窗口大小之前有效。这是替代List
颜色的另一种解决方法:
extension NSTableView {
open override func viewDidMoveToWindow() {
super.viewDidMoveToWindow()
backgroundColor = NSColor.clear
enclosingScrollView!.drawsBackground = false
}
}
潜在的缺点是,这将影响应用程序中的所有列表。
答案 1 :(得分:3)
第一张图片显示了问题的根源-所使用的滚动视图默认情况下是不透明的,因此添加的彩色背景在那里但不可见
因此解决方案是找到该滚动视图并禁用绘图背景
这里是解决此问题或解决方法的一种可能方法(但由于所有修改都是通过AppKit API进行的,因此无需硬编码即可有效)。实际上,这与关闭XIB中用于持有我们的tableview的scrollview的复选框相同。在Xcode 11.2 / macOS 10.15上进行了测试。
struct ScrollViewCleaner: NSViewRepresentable {
func makeNSView(context: NSViewRepresentableContext<ScrollViewCleaner>) -> NSView {
let nsView = NSView()
DispatchQueue.main.async { // on next event nsView will be in view hierarchy
if let scrollView = nsView.enclosingScrollView {
scrollView.drawsBackground = false
}
}
return nsView
}
func updateNSView(_ nsView: NSView, context: NSViewRepresentableContext<ScrollViewCleaner>) {
}
}
extension View {
func removingScrollViewBackground() -> some View {
self.background(ScrollViewCleaner())
}
}
struct TestListBackground: View {
var body: some View {
List()
{
ForEach(0..<3) { _ in
Text("Test")
.listRowBackground(Color.green)
}
.removingScrollViewBackground() // must be called _inside_ List
.background(Color.blue)
}.background(Color.red)
}
}
答案 2 :(得分:1)
很遗憾,ListStyle
协议没有记录,并且.listStyle
修饰符的用法非常有限,您可以从CarouselListStyle, DefaultListStyle, GroupedListStyle ,PlainListStyle, SidebarListStyle
中进行选择
尝试结合ScrollView和ForEach来模拟List,这为您提供了很大的灵活性,缺少的部分易于编写。一旦可供开发人员使用ListStyle,就可以轻松更改代码...
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)
}
}