如何在 SwiftUI 中更改表单的背景颜色?

Posted

技术标签:

【中文标题】如何在 SwiftUI 中更改表单的背景颜色?【英文标题】:How to change the background color for a Form in SwiftUI? 【发布时间】:2019-07-29 13:02:33 【问题描述】:

我想更改表单的“浅灰色”背景颜色,但 .foregroundColor(Color.blue).background(Color.blue) 似乎不起作用

struct ContentView : View 

 @State var value = ""

    var body: some View 
        Form 
            Section(header: Text("First Name")) 
                TextField($value)
            
            Section(header: Text("Last Name")) 
                TextField($value)
            
        .foregroundColor(Color.blue)

    

【问题讨论】:

您可能需要发布更多代码,因为像background 修饰符这样基本的东西感觉不是您的问题。这是一个模态弹出窗口吗?您在使用ZStack 吗?请给我们更多详细信息,或接受@Quinn 给出的答案。让我们重复这个问题。 @dfd 这是我唯一的视图,一个有 2 个字段的表单(它应该是一个注册表单),我可能会添加一个按钮,但没有任何弹出窗口或 ZStack。我已经在 Form 上尝试过.background(Color.blue),但它不起作用。我猜 Form 是一个特殊的视图,或者它只是一个错误,有人找到了解决方法 找到了。我会发布一个答案,如果您需要一些调整,请告诉我。 【参考方案1】:

可行的解决方案:

所有 SwiftUI 的 Lists 都由 ios 中的 UITableView 支持。所以你需要改变tableView的背景颜色。但是由于ColorUIColor的值略有不同,可以去掉UIColor

struct ContentView: View 
    
    init()
        UITableView.appearance().backgroundColor = .clear
    
    
    @State var value = ""
    
    var body: some View 
        Form 
            Section(header: Text("First Name")) 
                TextField("First Name", text: $value)
            
            Section(header: Text("Last Name")) 
                TextField("Last Name", text: $value)
            
        
        .foregroundColor(Color.blue)
        .background(Color.yellow)
    

现在您可以使用您想要的任何背景(包括所有Colors)

请注意那些顶部和底部的白色区域是安全的,您可以使用.edgesIgnoringSafeArea() 修饰符来消除它们。


恢复

由于UITableView.appearance().backgroundColor是全局应用的,你可以使用.onAppear修饰符在不同的视图中改变它(因为它是全局改变)。所以您可以使用另一个 onAppearonDisappear 将其重置 回到您想要的状态。

默认颜色为:

UIColor.systemGroupedBackground 用于分组样式。和

UIColor.systemBackground 代表简单风格

它们都自动支持暗模式和亮模式。

【讨论】:

UITableView.appearance().backgroundColor = .clear 普遍改变了样式,这不是一个理想的解决方案。但是,我找不到其他解决方案。 您可以使用.onAppear() 修饰符使其表现得像只针对该页面。 ;) @WilliamGrand 嗯,我在 Xcode 11.6 和 Xcode 12 beta 4 上的经验是,.onAppear() 普遍适用。 当然你应该使用 another onAppearonDisappear重置它回到你想要的;) @WilliamGrand 这对于 iOS 14 不再正确。UITableView 不再支持列表。【参考方案2】:

试试这个

.onAppear 
   UITableView.appearance().backgroundColor = .blue

【讨论】:

UITableView.appearance().backgroundColor = .blue 普遍改变了样式,这不是一个理想的解决方案。但是,我找不到其他解决方案。【参考方案3】:

上面 Mojtaba Hosseini 接受的答案有效,但 init() 语句不适用于 UITableView 语句。这是因为它“硬编码”了 ContentView 的初始化参数。在这种情况下,它没有,所以一切正常,但是如果将 @ObservedObject 添加到视图中,那么这将破坏 init 函数。

只需将 UITable 语句添加到 body,显式返回 Form 并删除 init(),就简单多了。

var body: some View 
    UITableView.appearance().backgroundColor = .clear
    return Form ...
 

但是,在Form 上设置背景颜色通常可以按预期工作。它在ContentView 屏幕上不起作用的事实可能是一个错误。

【讨论】:

错误:类型“()”不能符合“视图”;只有结构/枚举/类类型可以符合协议【参考方案4】:

如果您不想修改Form的安全区域,也可以使用ZStack

struct ContentView: View 
    
    init()
        
        UITableView.appearance().backgroundColor = .clear
    
    
    @State var value = ""
    
    var body: some View 
        ZStack 
            Color(UIColor.systemYellow)
                .edgesIgnoringSafeArea(.all)
            Form 
                Section(header: Text("First Name")) 
                    TextField("First Name", text: $value)
                
                Section(header: Text("Last Name")) 
                    TextField("Last Name", text: $value)
                
            
        
    

【讨论】:

【参考方案5】:

不要更改全局appearance()

例如,您可以使用UITableView.appearance().backgroundColor = .redForm 的背景颜色设置为红色。这可以进入视图的init,但这会影响每个 ListForm

或者,您可以使用SwiftUI-Introspect 来自定义一个,方法如下:

struct ContentView: View 
    @State private var value = ""

    var body: some View 
        Form 
            Section(header: Text("First Name")) 
                TextField("First", text: $value)
            

            Section(header: Text("Last Name")) 
                TextField("Last", text: $value)
            
        
        .introspectTableView  $0.backgroundColor = .systemBlue 
        .foregroundColor(Color.blue)
    

您还可以将以下内容添加到每个部分以使这些部分也变成蓝色:

.listRowBackground(Color.blue)

【讨论】:

【参考方案6】:

上面的解决方案对我想要实现的目标并没有真正起作用。我想要一个具有清晰背景的表单初始屏幕,以及具有默认 iOS systemGroupedBackground 颜色的后续屏幕。使用出现()和消失()对我不起作用,因为在各种选项卡之间切换会导致外观错误。

我想出了以下解决方案。它借鉴了上面的解决方案。

对于我的 ContentView 屏幕,我在 Struct 中插入了这段代码。

init()
    UITableView.appearance().backgroundColor = .clear

这是一个影响所有表单的全局变化。

对于我希望使用默认颜色的所有表单,我将这段代码插入到表单 之外。

.background(Color(.systemGroupedBackground))

【讨论】:

【参考方案7】:

将这些代码复制到您的每个 Form 视图下方:

Form 
    // Your form view 
 
.onAppear  // ADD THESE AFTER YOUR FORM VIEW
    UITableView.appearance().backgroundColor = .clear 

 .onDisappear  // CHANGE BACK TO SYSTEM's DEFAULT
    UITableView.appearance().backgroundColor = .systemGroupedBackground 
 
.background(.yellow) // Add your background color

【讨论】:

以上是关于如何在 SwiftUI 中更改表单的背景颜色?的主要内容,如果未能解决你的问题,请参考以下文章

在 SwiftUI 中更改 GroupBox 背景颜色

SwiftUI:如何使列表视图透明?如何更改列表视图背景颜色?

如何更改 SwiftUI 和 iOS 14 中的单元格背景颜色?

如何在 SwiftUI mac 应用程序中更改屏幕背景颜色?

SwiftUI:如何更改 NavigationView 的色调(背景颜色)?

更改 ScrollView SwiftUI 的背景颜色