【问题标题】:Remove/change section header background color in SwiftUI List删除/更改 SwiftUI 列表中的部分标题背景颜色
【发布时间】:2019-11-13 23:30:11
【问题描述】:

在 SwiftUI 中使用简单的List,如何更改/删除节标题的标准背景颜色

struct ContentView : View {
    var body: some View {
        List {
            ForEach(0...3) { section in
                Section(header: Text("Section")) {
                    ForEach(0...3) { row in
                        Text("Row")
                    }
                }
            }
        }
    }
}

【问题讨论】:

    标签: swiftui


    【解决方案1】:

    在 beta 4 中,relativeWidth 已被弃用。代码已更新以反映这一点。

    很遗憾,没有设置背景颜色的快速参数。但是,您仍然可以这样做:

    import SwiftUI
    
    struct ContentView : View {
        var body: some View {
            List {
                ForEach(0...3) { section in
                    Section(header:
                                CustomHeader(
                                    name: "Section Name",
                                    color: Color.yellow
                                )
                            ) {
                        ForEach(0...3) { row in
                            Text("Row")
                        }
                    }
                }
            }
        }
    }
    
    struct CustomHeader: View {
        let name: String
        let color: Color
    
        var body: some View {
            VStack {
                Spacer()
                HStack {
                    Text(name)
                    Spacer()
                }
                Spacer()
            }
            .padding(0).background(FillAll(color: color))
        }
    }
    
    struct FillAll: View {
        let color: Color
        
        var body: some View {
            GeometryReader { proxy in
                self.color.frame(width: proxy.size.width * 1.3).fixedSize()
            }
        }
    }
    

    【讨论】:

    • 在旋转设备时效果不佳。
    • iPhone XR。但是设置更大的 relativeWidth 可以解决这个问题。
    • 糟糕。我看到了。用更大的相对宽度更新了代码。
    • @AndreCarrera 当 relativeWidth 是一个有效选项时,答案被发回。代码已更新。
    • 目前此解决方案在 iOS 14.2 的横向模式下无法完全运行。它不尊重左侧的安全区域。
    【解决方案2】:

    另一种方法是设置标题的框架:

            VStack {
                List {
                    ForEach(0...3) { section in
                        Section(header:
                            Text("Section")
                                .frame(minWidth: 0, maxWidth: .infinity,alignment:.leading)
                                .background(Color.blue.relativeWidth(2))
                        ) {
                            ForEach(0...3) { row in
                                Text("Row")
                            }
                        }
                    }
                }
            }
    

    【讨论】:

    • 我必须对上述内容执行此操作才能使其正常工作。 Section(header: Text("Group").frame(minWidth: 0, maxWidth: .infinity,alignment: .leading).background(Color.gray))
    • 当我这样做时,它大部分工作得很好,但是彩色部分标题栏没有到达显示器的两侧,所以我在每一端都留下了一个小的灰色部分,这是相当令人失望的.你知道如何解决这个问题吗?
    • 相对宽度在 iOS 14.2 上不存在
    【解决方案3】:

    我尝试使用上面的自定义标头代码,但不幸的是无法让它在 beta 6 中工作。这导致我使用 ViewModifier:

    public struct sectionHeader: ViewModifier{
    var backgroundColor:Color
    var foregroundColor:Color
    public func body(content: Content) -> some View {
        content
        .padding(20)
        .frame(width: UIScreen.main.bounds.width, height: 28,alignment:
        .leading)
        .background(backgroundColor)
        .foregroundColor(foregroundColor)
    }}
    

    可以将其添加到列表中的部分,如下所示:

    struct ContentView: View {
    @ObservedObject var service = someService()
    var body: some View {
        NavigationView {
            List{
                ForEach(someService.sections) {section in
                    Section(header: Text(section.title).modifier(sectionHeader(backgroundColor: Color(.systemBlue), foregroundColor: Color(.white)))){
    

    希望对某人有所帮助!

    【讨论】:

    • 只要确保你没有将 .listStyle() 修饰符添加到列表中,因为这会将它自己的视图强加在节标题上。
    • 这在启动时有效,但在旋转时会损坏,因为宽度没有正确更新。此外,它不尊重景观中适当的安全区域大小。
    • 谢谢。这是唯一适合我的解决方案。
    【解决方案4】:

    建议的解决方案在您决定 clear 您的 List 标题背景颜色之前有效。

    List标头自定义颜色的更好解决方案:

    1.此解决方案会影响您应用中的所有 List 部分:(或将其移至您的 AppDelegate 类)

    struct ContentView: View {
    
    init() {
          UITableViewHeaderFooterView.appearance().tintColor = UIColor.clear
        }
    
    var body: some View {
        List {
            ForEach(0 ..< 3) { section in
                Section(header:
                        Text("Section")
                ) {
                    ForEach(0 ..< 3) { row in
                        Text("Row")
                    }
                }
            }
         }
      }
    }
    

    2.使用此解决方案,您可以为应用中的每个列表自定义 List 标题背景颜色:

    struct ContentView: View {
    init() {
        UITableViewHeaderFooterView.appearance().tintColor = UIColor.clear
    }
    
    var body: some View {
        List {
            ForEach(0 ..< 3) { section in
                Section(header:
                    HStack {
                        Text("Section")
                        Spacer()
                    }
                    .listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
                    .background(Color.blue)
    
                ) {
                    ForEach(0 ..< 3) { row in
                        Text("Row")
                    }
                }
            }
         }
      }
    }
    

    【讨论】:

    • @user832 我在 iOS 14.2 中使用它,它可以工作
    • 感谢您告诉我。我在我的部分标题中使用 NavigationLink,它导致了问题。我再次尝试了一些更改,并且成功了。
    • 为了清晰的背景,这个对我有用,'UITableViewHeaderFooterView.appearance().backgroundView = UIView()'
    【解决方案5】:

    无需更改所有列表的外观或做任何奇怪的事情,只需:

    1. (可选)如果您想要粘性标题,请将.listStyle(GroupedListStyle()) 放在List 上。
    2. 将部分上的listRowInsets 设置为0。
    3. Section.backgroundColor 设置为clear 以删除默认颜色,或者您想要为其着色的任何颜色。

    例子:

    List {
        Section(header: HStack {
            Text("Header")
                .font(.headline)
                .foregroundColor(.white)
                .padding()
    
                Spacer()
        }
        .background(Color.blue)
        .listRowInsets(EdgeInsets(
            top: 0,
            leading: 0,
            bottom: 0,
            trailing: 0))
        ) {
            // your list items
        }
    }.listStyle(GroupedListStyle()) // Leave off for sticky headers
    

    【讨论】:

    • 这不起作用。它对我所做的只是将标题(例如,“标题”)推到边缘,并在文本后面制作一条细蓝色带。部分标题的灰色仍然存在。
    • 起初这不起作用,直到我意识到我已经将 .listStyle(GroupedListStyle()) 留在了列表中。一旦我删除它,这个解决方案也有效。
    • 我会更新我的答案,让更多人关注这一步
    • 但我不想要 GroupedListStyle() 我想要粘性标题
    • 我得到了很好的结果,但不得不不使用第 1 步,我注意到上面的示例本身没有设置 GroupedListStyle。
    【解决方案6】:

    通过使用自定义修饰符,我能够使标题变得清晰(在我的情况下变成白色)。我需要使用 listStyle() 修饰符,但以上所有方法都不适合我。

    希望对其他人有所帮助!

    List {
        Section(header: HStack {
            Text("Header Text")
                .font(.headline)
                .padding()
    
                Spacer()
        }
        ) {
    ForEach(0...3) { row in
                            Text("Row")
                        }
        }
    }.listStyle(GroupedListStyle()).listSeparatorStyle()
    
    public struct ListSeparatorStyleModifier: ViewModifier {
        public func body(content: Content) -> some View {
            content.onAppear {
                UITableView.appearance().separatorStyle = .singleLine
                UITableView.appearance().separatorInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
                UITableViewHeaderFooterView.appearance().tintColor = .clear
                UITableView.appearance().backgroundColor = .clear // tableview background
                UITableViewCell.appearance().backgroundColor = .clear
    
            }
        }
    }
    
    extension View {
        public func listSeparatorStyle() -> some View {
            modifier(ListSeparatorStyleModifier())
        }
    }
    
    

    【讨论】:

    • 如果没有 GroupedListStyle,这对 iOS 14.2 没有影响。部分背景颜色保持默认灰色。看来 UITableViewHeaderFooterView 不再是图片的一部分了。
    • 完美。像魅力一样工作..继续回答兄弟
    【解决方案7】:

    您必须在标题部分的视图上使用与 .listRowInsets 组合的矩形

    Section(header: headerSectionView) {
        Text("MySection")
    }
    
    
    private var headerSectionView: some View {
        Rectangle()
            .fill(Color.blue) // will make a blue header background
            .listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
            .overlay(
                Text("My Section Title")
                    .padding(.horizontal), // You need this to add back the padding
                alignment: .leading
            )
    }
    
    

    【讨论】:

    • 这是唯一对我有用的解决方案
    【解决方案8】:

    我找到了更好的解决方案

    UITableViewHeaderFooterView.appearance().backgroundView = .init()
    

    【讨论】:

      猜你喜欢
      • 2013-01-03
      • 1970-01-01
      • 1970-01-01
      • 2017-09-19
      • 1970-01-01
      • 2021-09-22
      • 2019-11-29
      • 1970-01-01
      相关资源
      最近更新 更多