如何在 SwiftUI 中修改列表的背景颜色?
How do I modify the background color of a List in SwiftUI?
我正在尝试重新创建我在 Swift 中使用 UIKit 构建的 UIUI,但我 运行 遇到了一些小问题。
我想在这里更改 List
的颜色,但是 属性 似乎没有像我预期的那样工作。示例代码如下:
struct ListView: View {
@EnvironmentObject var listData: ListData
var body: some View {
NavigationView {
List(listData.items) { item in
ListItemCell(item: item)
}
.content.background(Color.yellow) // not sure what content is defined as here
.background(Image("paper-3")) // this is the entire screen
}
}
}
struct ListItemCell: View {
let item: ListItem
var body: some View {
NavigationButton(destination: Text(item.name)) {
Text("\(item.name) ........................................................................................................................................................................................................")
.background(Color.red) // not the area I'm looking for
}.background(Color.blue) // also not the area I'm looking for
}
}
我能够通过使用 colorMultiply(Color:) 使整个列表改变颜色。只需将此修饰符添加到列表视图的末尾,然后填充会将 table 推到设备边缘。例如:
List {...}.colorMultiply(Color.green).padding(.top)
好的,我找到了为列表行着色的解决方案:
struct TestRow: View {
var body: some View {
Text("This is a row!")
.listRowBackground(Color.green)
}
}
然后在正文中:
List {
TestRow()
TestRow()
TestRow()
}
这如我所料,但我还没有找到如何删除行之间的分隔线...
如果尝试使用 .listRowBackground
并应用 .padding
通过 SwiftUI 创建浮动类型单元格,有人可能会发现这很有用
var body: some View {
NavigationView {
List {
ForEach (site) { item in
HStack {
Text(String(item.id))
VStack(alignment: .leading) {
Text(item.name)
Text(item.crop[0])
}
}.listRowBackground(Color.yellow)
.padding(.trailing, 5)
.padding(.leading, 5)
.padding(.top, 2)
.padding(.bottom, 2))
}
}
.navigationBarTitle(Text("Locations"))
}
}
我假设 listRowPlatterColor
修饰符应该这样做,但从 Xcode 11 Beta 11M336w
var body: some View {
List(pokemon) { pokemon in
PokemonCell(pokemon: pokemon)
.listRowPlatterColor(.green)
}
}
我不知道有什么联系,但如果你用 Form
包裹列表,它就可以工作。
Form {
List(viewModel.currencyList, id: \.self) { currency in
ItemView(item: currency)
}
.listRowBackground(Color("Primary"))
.background(Color("Primary"))
}
您可以通过更改 UITableView
的外观来实现。
UITableView.appearance().backgroundColor = UIColor.clear
只需将此行放在Appdelegate
的didFinishLaunchingWithOptions
方法中即可。
代替 UIColor.clear
设置要添加到 list
.
背景色中的任何颜色
struct ContentView: View {
var strings = ["a", "b"]
var body: some View {
List {
ForEach(strings, id: \.self) { string in
Text(string)
}.listRowBackground(Color.green)
}
}
}
我启发了一些用于配置每页 NavigationView 导航栏样式的配置器,并为每页配置器编写了一些简单的 UITableView 不使用 UITableView.appearance() 全局方法
import SwiftUI
struct TableViewConfigurator: UIViewControllerRepresentable {
var configure: (UITableView) -> Void = { _ in }
func makeUIViewController(context: UIViewControllerRepresentableContext<TableViewConfigurator>) -> UIViewController {
UIViewController()
}
func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<TableViewConfigurator>) {
let tableViews = uiViewController.navigationController?.topViewController?.view.subviews(ofType: UITableView.self) ?? [UITableView]()
for tableView in tableViews {
self.configure(tableView)
}
}
}
然后需要 UIView 扩展来查找所有 UITableViews
extension UIView {
func subviews<T:UIView>(ofType WhatType:T.Type) -> [T] {
var result = self.subviews.compactMap {[=11=] as? T}
for sub in self.subviews {
result.append(contentsOf: sub.subviews(ofType:WhatType))
}
return result
}
}
最后的用法是:
List {
}.background(TableViewConfigurator {
[=12=].backgroundColor = .red
})
也许应该改进一件事,那就是使用 navigationController?.topViewController 使其即使在视图控制器层次结构中没有 navigationController 也能正常工作
对我来说,在SwiftUI中改变List背景的完美方案是:
struct SomeView: View {
init(){
UITableView.appearance().backgroundColor = UIColor(named: "backgroundLight")
}
...
}
这会将整个列表的背景设置为绿色:
init() {
UITableView.appearance().separatorStyle = .none
UITableViewCell.appearance().backgroundColor = .green
UITableView.appearance().backgroundColor = .green
}
列表还不完善。
一种选择是像这样使用它 -> List { ForEach(elements) { }}
而不是 List($elements)
在我看来,这是迄今为止效果最好的方法。
正如@FontFamily 所说,它不应该破坏任何 List
默认行为,例如滑动。
.colorMultiply(...)
作为选项,您可以 .colorMultiply(Color.yourColor)
修饰符。
警告:这不会改变颜色!这只会将 Multiply
修饰符应用于当前颜色。请在执行任何操作之前阅读问题,因为您可能正在寻找:“How to CHANGE the background color of a List in SwiftUI”,这对您不起作用。 ❄️
示例:
List (elements, id:\.self ) { element in
Text(element)
}
.colorMultiply(Color.red) <--------- replace with your color
SwiftUI中有一个参数:listRowBackground(),但是如果直接用List迭代数据采集,是不行的。
这是我的解决方法:
List {
// To make the background transparent, we have we use a ForEach as a wrapper
ForEach(files) {file in
Label(
title: { Text(file.name ?? fileOptionalFiller).lineLimit(listRowTextLineLimit) },
icon: { AppIcon.doc.foregroundColor(.primary) }
)
}
.listRowBackground(Color.primary.colorInvert())
}
基本上,如果您在 List 中使用 ForEach,listRowBackground() 就可以工作。
如果有人来这里寻找 iPhone X/11 上横向背景不是全宽的解决方案,请尝试:
.listRowBackground(Color("backgroundColour").edgesIgnoringSafeArea(.all))
Xcode 版本 12.4
背景 属性 对我有用,但必须使用 Opacity。
没有 opacity 是行不通的。
List {
ForEach(data, id: \.id) { (item) in
ListRow(item)
.environmentObject(self.data)
}
}
.background(Color.black)
.opacity(0.5)
struct Details: View {
var body: some View {
Spacer().overlay(
List {
Text("Hello World!").font(.title2)
.listRowBackground(Color.clear)
Text("Hello World again").font(.title2)
.listRowBackground(Color.clear)
}.onAppear() {
UITableView.appearance().backgroundColor = UIColor.green
UITableViewCell.appearance().backgroundColor = UIColor.green
}
)
}
}
更改背景颜色
如其他人所述,更改 UITableView 背景会影响您应用中的所有其他列表。
但是,如果您想要不同的背景颜色,您可以将默认设置为 clear,并在 swiftui 视图中设置背景颜色,如下所示:
List {
Text("Item 1")
Text("Item 2")
Text("Item 3")
}
// Ignore safe area to take up whole screen
.background(Color.purple.ignoresSafeArea())
.onAppear {
// Set the default to clear
UITableView.appearance().backgroundColor = .clear
}
您可能希望更早地设置表视图外观,例如在 SceneDelegate 或根视图中,如下所示:
// SceneDelegate
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = scene as? UIWindowScene else {
print("Returning because screne does not exist")
return
}
// Set here
UITableView.appearance().backgroundColor = .clear
let contentView = ContentView()
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: contentView)
self.window = window
window.makeKeyAndVisible()
}
// Root App View
@main
struct ListBackgroundApp: App {
init() {
UITableView.appearance().backgroundColor = .clear
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
2022,MacOS 解决方案
以下代码使所有 List
的背景颜色透明:
// Removes background from List in SwiftUI
extension NSTableView {
open override func viewDidMoveToWindow() {
super.viewDidMoveToWindow()
backgroundColor = NSColor.clear
if let esv = enclosingScrollView {
esv.drawsBackground = false
}
}
}
........
........
........
以下代码使所有 TextEditor
的背景颜色透明:
extension NSTextView {
open override var frame: CGRect {
didSet {
backgroundColor = .clear
drawsBackground = true
}
}
}
Islom Alimov 的回答 在我看来似乎是迄今为止最好的实现。
唯一缺点:这也会更改您应用中所有其他列表视图的背景颜色,因此您需要手动将它们改回原样,除非您希望各处都使用相同的颜色。
这是一个示例视图:
import SwiftUI
struct TestView1: View {
init(){
UITableView.appearance().backgroundColor = UIColor(Color.clear)
}
@State var data = ["abc", "def"]
var body: some View {
VStack {
List {
ForEach(data, id: \.self) {element in
Text("\(String(describing: element))")
}
.background(Color.green)
.listRowBackground(Color.blue)
}
.background(Color.yellow)
Spacer()
Color.red
}
}
}
struct TestView1_Previews: PreviewProvider {
static var previews: some View {
TestView1()
}
}
产生:
如果您想避免全局设置所有 table 视图的外观,您可以将 UITableView.appearance(whenContainedInInstancesOf:)
与 UIHostingController
结合使用。感谢 DanSkeel 您在上面留下的指出这一点的评论。我是这样使用它的:
public class ClearTableViewHostingController<Content>: UIHostingController<Content> where Content: View {
public override func viewDidLoad() {
UITableView.appearance(whenContainedInInstancesOf: [ClearTableViewHostingController<Content>.self]).backgroundColor = .clear
}
}
您可以这样使用 ClearTableViewHostingController
:
let view = MyListView()
let viewController = ClearTableViewHostingController(coder: coder, rootView: view)
然后在您的视图中,您可以像这样设置列表背景颜色:
List {
Text("Hello World")
}
.background(Color.gray)
只需在init()
方法中添加UITableView
外观背景颜色,添加列表样式(.listStyle(SidebarListStyle())
。不要忘记导入 UIKit
模块
struct HomeScreen: View {
init() {
UITableView.appearance().backgroundColor = .clear
}
let tempData:[TempData] = [TempData( name: "abc"),
TempData( name: "abc"),
TempData( name: "abc"),
TempData( name: "abc")]
var body: some View {
ZStack {
Image("loginBackgound")
.resizable()
.scaledToFill()
List{
ForEach(tempData){ data in
Text(data.name)
}
}
.listStyle(SidebarListStyle())
}
.ignoresSafeArea(edges: .all)
}
}
将扩展列表设为:
extension List{
@available(iOS 14, *)
func backgroundList(_ color: Color = .clear) -> some View{
UITableView.appearance().backgroundColor = UIColor(color)
return self
}
}
使用 UITableView.appearance().backgroundColor 不是一个好主意 因为它改变了所有 table秒。我找到了一个在 iOS 14、15.
中选择的确切 table 颜色更改的有效解决方案
我们将使用需要在列表中应用的修饰符来更改颜色
extension View {
func backgroundTableModifier(_ color: UIColor? = nil) -> some View {
self.modifier(BackgroundTableModifier(color: color))
}
}
我们的任务是找到 UITableView,然后更改颜色。
private struct BackgroundTableModifier: ViewModifier {
private let color: UIColor?
@State private var tableView: UITableView?
init(color: UIColor?) {
self.color = color
}
public func body(content: Content) -> some View {
if tableView?.backgroundColor != color {
content
.overlay(BackgroundTableViewRepresentable(tableBlock: { tableView in
tableView.backgroundColor = color
self.tableView = tableView
}))
} else {
content
}
}
}
private struct BackgroundTableViewRepresentable: UIViewRepresentable {
var tableBlock: (UITableView) -> ()
func makeUIView(context: Context) -> BackgroundTableView {
let view = BackgroundTableView(tableBlock: tableBlock)
return view
}
func updateUIView(_ uiView: BackgroundTableView, context: Context) {}
}
class BackgroundTableView: UIView {
var tableBlock: (UITableView) -> ()
init(tableBlock: @escaping (UITableView) -> ()) {
self.tableBlock = tableBlock
super.init(frame: .zero)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
if let tableView = findTableView(in: self) {
tableBlock(tableView)
}
}
private func findTableView(in view: UIView) -> UITableView? {
if let tableView = view as? UITableView {
return tableView
}
if let superView = view.superview {
return findTableView(in: superView)
}
return nil
}
}
为了找到UITableView,修饰符必须在List里面。当然,您需要确保只调用一次修饰符,而不需要将它应用于每一行。这是一个用法示例
List {
rows()
.backgroundTableModifier(.clear)
}
func rows() -> some View {
ForEach(0..<10, id: \.self) { index in
Row()
}
}
您可以使用 Github 中的 introspect
库来设置基础 table 视图的背景颜色,如下所示:
List { ... } .introspectTableView { tableView in
tableView.backgroundColor = .yellow
}
由于某些原因颜色更改不起作用,您可以尝试将 .listStyle 更改为 .plain
代码:
struct ContentView: View {
var body: some View {
VStack {
Text("Test")
List {
ForEach(1 ..< 4) { items in
Text(String(items))
}
}
.listStyle(.plain)
}
}
我正在尝试重新创建我在 Swift 中使用 UIKit 构建的 UIUI,但我 运行 遇到了一些小问题。
我想在这里更改 List
的颜色,但是 属性 似乎没有像我预期的那样工作。示例代码如下:
struct ListView: View {
@EnvironmentObject var listData: ListData
var body: some View {
NavigationView {
List(listData.items) { item in
ListItemCell(item: item)
}
.content.background(Color.yellow) // not sure what content is defined as here
.background(Image("paper-3")) // this is the entire screen
}
}
}
struct ListItemCell: View {
let item: ListItem
var body: some View {
NavigationButton(destination: Text(item.name)) {
Text("\(item.name) ........................................................................................................................................................................................................")
.background(Color.red) // not the area I'm looking for
}.background(Color.blue) // also not the area I'm looking for
}
}
我能够通过使用 colorMultiply(Color:) 使整个列表改变颜色。只需将此修饰符添加到列表视图的末尾,然后填充会将 table 推到设备边缘。例如:
List {...}.colorMultiply(Color.green).padding(.top)
好的,我找到了为列表行着色的解决方案:
struct TestRow: View {
var body: some View {
Text("This is a row!")
.listRowBackground(Color.green)
}
}
然后在正文中:
List {
TestRow()
TestRow()
TestRow()
}
这如我所料,但我还没有找到如何删除行之间的分隔线...
如果尝试使用 .listRowBackground
并应用 .padding
var body: some View {
NavigationView {
List {
ForEach (site) { item in
HStack {
Text(String(item.id))
VStack(alignment: .leading) {
Text(item.name)
Text(item.crop[0])
}
}.listRowBackground(Color.yellow)
.padding(.trailing, 5)
.padding(.leading, 5)
.padding(.top, 2)
.padding(.bottom, 2))
}
}
.navigationBarTitle(Text("Locations"))
}
}
我假设 listRowPlatterColor
修饰符应该这样做,但从 Xcode 11 Beta 11M336w
var body: some View {
List(pokemon) { pokemon in
PokemonCell(pokemon: pokemon)
.listRowPlatterColor(.green)
}
}
我不知道有什么联系,但如果你用 Form
包裹列表,它就可以工作。
Form {
List(viewModel.currencyList, id: \.self) { currency in
ItemView(item: currency)
}
.listRowBackground(Color("Primary"))
.background(Color("Primary"))
}
您可以通过更改 UITableView
的外观来实现。
UITableView.appearance().backgroundColor = UIColor.clear
只需将此行放在Appdelegate
的didFinishLaunchingWithOptions
方法中即可。
代替 UIColor.clear
设置要添加到 list
.
struct ContentView: View {
var strings = ["a", "b"]
var body: some View {
List {
ForEach(strings, id: \.self) { string in
Text(string)
}.listRowBackground(Color.green)
}
}
}
我启发了一些用于配置每页 NavigationView 导航栏样式的配置器,并为每页配置器编写了一些简单的 UITableView 不使用 UITableView.appearance() 全局方法
import SwiftUI
struct TableViewConfigurator: UIViewControllerRepresentable {
var configure: (UITableView) -> Void = { _ in }
func makeUIViewController(context: UIViewControllerRepresentableContext<TableViewConfigurator>) -> UIViewController {
UIViewController()
}
func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<TableViewConfigurator>) {
let tableViews = uiViewController.navigationController?.topViewController?.view.subviews(ofType: UITableView.self) ?? [UITableView]()
for tableView in tableViews {
self.configure(tableView)
}
}
}
然后需要 UIView 扩展来查找所有 UITableViews
extension UIView {
func subviews<T:UIView>(ofType WhatType:T.Type) -> [T] {
var result = self.subviews.compactMap {[=11=] as? T}
for sub in self.subviews {
result.append(contentsOf: sub.subviews(ofType:WhatType))
}
return result
}
}
最后的用法是:
List {
}.background(TableViewConfigurator {
[=12=].backgroundColor = .red
})
也许应该改进一件事,那就是使用 navigationController?.topViewController 使其即使在视图控制器层次结构中没有 navigationController 也能正常工作
对我来说,在SwiftUI中改变List背景的完美方案是:
struct SomeView: View {
init(){
UITableView.appearance().backgroundColor = UIColor(named: "backgroundLight")
}
...
}
这会将整个列表的背景设置为绿色:
init() {
UITableView.appearance().separatorStyle = .none
UITableViewCell.appearance().backgroundColor = .green
UITableView.appearance().backgroundColor = .green
}
列表还不完善。
一种选择是像这样使用它 -> List { ForEach(elements) { }}
而不是 List($elements)
在我看来,这是迄今为止效果最好的方法。
正如@FontFamily 所说,它不应该破坏任何 List
默认行为,例如滑动。
.colorMultiply(...)
作为选项,您可以 .colorMultiply(Color.yourColor)
修饰符。
警告:这不会改变颜色!这只会将 Multiply
修饰符应用于当前颜色。请在执行任何操作之前阅读问题,因为您可能正在寻找:“How to CHANGE the background color of a List in SwiftUI”,这对您不起作用。 ❄️
示例:
List (elements, id:\.self ) { element in
Text(element)
}
.colorMultiply(Color.red) <--------- replace with your color
SwiftUI中有一个参数:listRowBackground(),但是如果直接用List迭代数据采集,是不行的。
这是我的解决方法:
List {
// To make the background transparent, we have we use a ForEach as a wrapper
ForEach(files) {file in
Label(
title: { Text(file.name ?? fileOptionalFiller).lineLimit(listRowTextLineLimit) },
icon: { AppIcon.doc.foregroundColor(.primary) }
)
}
.listRowBackground(Color.primary.colorInvert())
}
基本上,如果您在 List 中使用 ForEach,listRowBackground() 就可以工作。
如果有人来这里寻找 iPhone X/11 上横向背景不是全宽的解决方案,请尝试:
.listRowBackground(Color("backgroundColour").edgesIgnoringSafeArea(.all))
Xcode 版本 12.4
背景 属性 对我有用,但必须使用 Opacity。 没有 opacity 是行不通的。
List {
ForEach(data, id: \.id) { (item) in
ListRow(item)
.environmentObject(self.data)
}
}
.background(Color.black)
.opacity(0.5)
struct Details: View {
var body: some View {
Spacer().overlay(
List {
Text("Hello World!").font(.title2)
.listRowBackground(Color.clear)
Text("Hello World again").font(.title2)
.listRowBackground(Color.clear)
}.onAppear() {
UITableView.appearance().backgroundColor = UIColor.green
UITableViewCell.appearance().backgroundColor = UIColor.green
}
)
}
}
更改背景颜色
如其他人所述,更改 UITableView 背景会影响您应用中的所有其他列表。
但是,如果您想要不同的背景颜色,您可以将默认设置为 clear,并在 swiftui 视图中设置背景颜色,如下所示:
List {
Text("Item 1")
Text("Item 2")
Text("Item 3")
}
// Ignore safe area to take up whole screen
.background(Color.purple.ignoresSafeArea())
.onAppear {
// Set the default to clear
UITableView.appearance().backgroundColor = .clear
}
您可能希望更早地设置表视图外观,例如在 SceneDelegate 或根视图中,如下所示:
// SceneDelegate
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = scene as? UIWindowScene else {
print("Returning because screne does not exist")
return
}
// Set here
UITableView.appearance().backgroundColor = .clear
let contentView = ContentView()
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: contentView)
self.window = window
window.makeKeyAndVisible()
}
// Root App View
@main
struct ListBackgroundApp: App {
init() {
UITableView.appearance().backgroundColor = .clear
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
2022,MacOS 解决方案
以下代码使所有 List
的背景颜色透明:
// Removes background from List in SwiftUI
extension NSTableView {
open override func viewDidMoveToWindow() {
super.viewDidMoveToWindow()
backgroundColor = NSColor.clear
if let esv = enclosingScrollView {
esv.drawsBackground = false
}
}
}
........
........
........
以下代码使所有 TextEditor
的背景颜色透明:
extension NSTextView {
open override var frame: CGRect {
didSet {
backgroundColor = .clear
drawsBackground = true
}
}
}
Islom Alimov 的回答
唯一缺点:这也会更改您应用中所有其他列表视图的背景颜色,因此您需要手动将它们改回原样,除非您希望各处都使用相同的颜色。
这是一个示例视图:
import SwiftUI
struct TestView1: View {
init(){
UITableView.appearance().backgroundColor = UIColor(Color.clear)
}
@State var data = ["abc", "def"]
var body: some View {
VStack {
List {
ForEach(data, id: \.self) {element in
Text("\(String(describing: element))")
}
.background(Color.green)
.listRowBackground(Color.blue)
}
.background(Color.yellow)
Spacer()
Color.red
}
}
}
struct TestView1_Previews: PreviewProvider {
static var previews: some View {
TestView1()
}
}
产生:
如果您想避免全局设置所有 table 视图的外观,您可以将 UITableView.appearance(whenContainedInInstancesOf:)
与 UIHostingController
结合使用。感谢 DanSkeel 您在上面留下的指出这一点的评论。我是这样使用它的:
public class ClearTableViewHostingController<Content>: UIHostingController<Content> where Content: View {
public override func viewDidLoad() {
UITableView.appearance(whenContainedInInstancesOf: [ClearTableViewHostingController<Content>.self]).backgroundColor = .clear
}
}
您可以这样使用 ClearTableViewHostingController
:
let view = MyListView()
let viewController = ClearTableViewHostingController(coder: coder, rootView: view)
然后在您的视图中,您可以像这样设置列表背景颜色:
List {
Text("Hello World")
}
.background(Color.gray)
只需在init()
方法中添加UITableView
外观背景颜色,添加列表样式(.listStyle(SidebarListStyle())
。不要忘记导入 UIKit
模块
struct HomeScreen: View {
init() {
UITableView.appearance().backgroundColor = .clear
}
let tempData:[TempData] = [TempData( name: "abc"),
TempData( name: "abc"),
TempData( name: "abc"),
TempData( name: "abc")]
var body: some View {
ZStack {
Image("loginBackgound")
.resizable()
.scaledToFill()
List{
ForEach(tempData){ data in
Text(data.name)
}
}
.listStyle(SidebarListStyle())
}
.ignoresSafeArea(edges: .all)
}
}
将扩展列表设为:
extension List{
@available(iOS 14, *)
func backgroundList(_ color: Color = .clear) -> some View{
UITableView.appearance().backgroundColor = UIColor(color)
return self
}
}
使用 UITableView.appearance().backgroundColor 不是一个好主意 因为它改变了所有 table秒。我找到了一个在 iOS 14、15.
中选择的确切 table 颜色更改的有效解决方案我们将使用需要在列表中应用的修饰符来更改颜色
extension View {
func backgroundTableModifier(_ color: UIColor? = nil) -> some View {
self.modifier(BackgroundTableModifier(color: color))
}
}
我们的任务是找到 UITableView,然后更改颜色。
private struct BackgroundTableModifier: ViewModifier {
private let color: UIColor?
@State private var tableView: UITableView?
init(color: UIColor?) {
self.color = color
}
public func body(content: Content) -> some View {
if tableView?.backgroundColor != color {
content
.overlay(BackgroundTableViewRepresentable(tableBlock: { tableView in
tableView.backgroundColor = color
self.tableView = tableView
}))
} else {
content
}
}
}
private struct BackgroundTableViewRepresentable: UIViewRepresentable {
var tableBlock: (UITableView) -> ()
func makeUIView(context: Context) -> BackgroundTableView {
let view = BackgroundTableView(tableBlock: tableBlock)
return view
}
func updateUIView(_ uiView: BackgroundTableView, context: Context) {}
}
class BackgroundTableView: UIView {
var tableBlock: (UITableView) -> ()
init(tableBlock: @escaping (UITableView) -> ()) {
self.tableBlock = tableBlock
super.init(frame: .zero)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
if let tableView = findTableView(in: self) {
tableBlock(tableView)
}
}
private func findTableView(in view: UIView) -> UITableView? {
if let tableView = view as? UITableView {
return tableView
}
if let superView = view.superview {
return findTableView(in: superView)
}
return nil
}
}
为了找到UITableView,修饰符必须在List里面。当然,您需要确保只调用一次修饰符,而不需要将它应用于每一行。这是一个用法示例
List {
rows()
.backgroundTableModifier(.clear)
}
func rows() -> some View {
ForEach(0..<10, id: \.self) { index in
Row()
}
}
您可以使用 Github 中的 introspect
库来设置基础 table 视图的背景颜色,如下所示:
List { ... } .introspectTableView { tableView in
tableView.backgroundColor = .yellow
}
由于某些原因颜色更改不起作用,您可以尝试将 .listStyle 更改为 .plain
代码:
struct ContentView: View {
var body: some View {
VStack {
Text("Test")
List {
ForEach(1 ..< 4) { items in
Text(String(items))
}
}
.listStyle(.plain)
}
}