如何在SwiftUI中修改列表的背景颜色?

134

我正在尝试使用SwiftUI重新创建我之前用UIKit构建的用户界面,但是我遇到了一些小问题。

我想要更改这里 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
    }
}

我想改变白色区域


这对我有用。将其添加到我的ContentView_Previews中。当您使用List时,请确保顶部的任何堆栈都在顶部具有spacer。.edgesIgnoringSafeArea(.all) 喜欢调皮捣蛋。 - Alias111
在另一个答案的帮助下,我能够像您的屏幕截图一样以不同的方式为列表中的每个元素着色。https://dev59.com/CVMI5IYBdhLWcg3wUZyd#69514684 - charelf
对于任何未来的观众,这是 iOS 16 版本 https://dev59.com/ClEG5IYBdhLWcg3wI06g#72650158 - Timmy
30个回答

7
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
            }
        )
    }
}

7

我认为Islom Alimov的答案https://dev59.com/CVMI5IYBdhLWcg3wUZyd#59970379是目前最好的实现。

唯一的缺点:这也会更改应用程序中所有其他列表视图的背景颜色,因此您需要手动将它们改回来,除非您希望在任何地方都有相同的颜色。

以下是示例视图:

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()
    }
}

生成:


6

如果您尝试使用 .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"))
    }
}

嗨@caleb81389,这对我有效,但它不适用于空行。你有任何想法为什么吗? - Omri Shapira
1
不好意思,我不知道如何将其应用于空行。也许你可以在标签或其他地方人为地放置空格文本“ ”……?除此之外,SwiftUI 有点任性,这样的问题需要比我更熟练的人来回答。 - caleb81389
如果你解决了这个问题,请告诉我! - caleb81389

3
我假设 listRowPlatterColor 修饰符应该可以实现这个功能,但在Xcode 11 beta 11M336w中却没有。
var body: some View {
    List(pokemon) { pokemon in
        PokemonCell(pokemon: pokemon)
            .listRowPlatterColor(.green)
    }
}

1
listRowPlatterColor现已被弃用,仅适用于watchOS。 - ixany

3

.colorMultiply(...)

作为一个选项,你可以使用.colorMultiply(Color.yourColor)修饰符。

警告这不会改变颜色!这只是将Multiply修饰符应用于当前颜色。在执行任何操作之前,请先阅读问题,因为您可能正在寻找“如何更改SwiftUI中List的背景颜色”,而这对您没用。❄️

示例:

List (elements, id:\.self ) { element in

     Text(element)

}
.colorMultiply(Color.red) <--------- replace with your color

enter image description here


工作得很好,但是如果用户切换到暗模式,它就会失败。我认为这是SwiftUI的一个bug。 - Markon
这只是覆盖了一个更酷的颜色并进行了乘法计算,它不会改变当前的颜色。 - Mane Manero
@ManeManero 我想知道你是否看了帖子的问题:“如何在SwiftUI中修改列表的背景颜色?”这并不改变颜色,而是修改它。对于深色模式,是的,您需要添加更多特定更改的逻辑/条件。 - Pedro Trujillo
这将会破坏行背景颜色。 - Ben
不适用于暗色主题,这个解决方案是无用的。 - Andrew_STOP_RU_WAR_IN_UA
如果您只是为了调试布局而更改颜色,那么这是一个简单的解决方案。 - Chris

3
在iOS 16中,我们通过scrollcontentbackground修饰符获得了一种本地方法来实现这一点。
您可以通过将颜色(ShapeStyle)设置为scrollcontentbackground来更改颜色。
List {
    Text("Item 1")
    Text("Item 2")
    Text("Item 3")
}
.scrollContentBackground(Color.pink)

或者您可以使用 .scrollContentBackground(.hidden) 隐藏背景,并使用 .background 修改器设置自定义背景。
List {
    Text("Item 1")
    Text("Item 2")
    Text("Item 3")
}
.background {
    Image("ventura")

}
.scrollContentBackground(.hidden)

2
尽管iPadOS 16 Beta Release Notes中提到.scrollContentBackground“允许自定义可滚动视图(如列表)的背景颜色”,但根据文档,它目前仍然受限于Visibility。也许在iPadOS 16发布时会有所改变。 - Oliver

2
由于某些原因,颜色更改无法正常工作,您可以尝试使用.listStyle设置为.plain。
代码:
struct ContentView: View {
var body: some View {
    VStack {
        Text("Test")

        List {
            ForEach(1 ..< 4) { items in
                Text(String(items))
            }
        }
        .listStyle(.plain)
    }
}

2

更换背景对我来说不起作用,因为系统背景的原因。我需要隐藏它。

List(examples) { example in
        ExampleRow(example: example)
    }.background(Color.white.edgesIgnoringSafeArea(.all))
        .scrollContentBackground(.hidden)

2

只需在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)
}
}

2

列表还不完美。

一个选项是像这样使用 -> List { ForEach(elements) { }} 而不是 List($elements)

在我的端上,这是目前最好的解决方法。 就像@FontFamily所说的那样,它不应该破坏任何List默认行为,比如滑动。


1
这会破坏嵌套列表项的onDelete和onMove功能。 - FontFamily
2
第二个例子会受到影响吗?我认为使用 List { ForEach(elements) } 应该没问题,对吧? - Oleg G.
2
你是对的 - 它确实适用于你给出的第二个例子。 - FontFamily

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接