Change GroupBox background color in SwiftUI

Viewed 3077

How can I change the default gray background color of a GroupBox view in SwiftUI?

I tried adding a background modifier, but this just changes the white background underneath the box (see screenshot).

GroupBox(label: Text("Label"), content: {
    Text("Content")
})
.background(Color.blue)

SwiftUI GroupBox screencapture with gray background and blue corners

3 Answers

This is default group box style. You can create whatever group box needed using custom style.

Here is an example. Tested with Xcode 12 / iOS 14.

demo

struct DemoGroupBox: View {
    var body: some View {
        GroupBox(label: Text("Label"), content: {
             Text("Content")
        })
        .groupBoxStyle(TransparentGroupBox())
        .padding()
    }
}

struct TransparentGroupBox: GroupBoxStyle {
    func makeBody(configuration: Configuration) -> some View {
        configuration.content
            .frame(maxWidth: .infinity)
            .padding()
            .background(RoundedRectangle(cornerRadius: 8).fill(Color.blue))
            .overlay(configuration.label.padding(.leading, 4), alignment: .topLeading)
    }
}

This problem can be solved in this way

Tested on iOS 16, Xcode 14.0 Beta

struct TestView: View {
    var body: some View {
        GroupBox(label: Text("Label"), content: {
            Text("Content")
        })
        .groupBoxStyle(ColoredGroupBox())
        .padding()
    }
}

struct ColoredGroupBox: GroupBoxStyle {
    func makeBody(configuration: Configuration) -> some View {
        VStack {
            HStack {
                configuration.label
                    .font(.headline)
                Spacer()
            }
            
            configuration.content
        }
        .padding()
        .background(RoundedRectangle(cornerRadius: 8, style: .continuous)
            .fill(.blue)) // Set your color here!!
    }
}

Result: enter image description here

Full code for above result

struct TestView: View {
    var body: some View {
        VStack {
            Divider()

            HStack {
                Text("Asperi's solution")
                Text("(Problematic with label)")
                    .bold()
            }
            
            GroupBox(label: Text("Label"), content: {
                Text("Content")
            })
            .groupBoxStyle(TransparentGroupBox())
            .padding()
            
            Divider()
            
            Text("My Solution")
            GroupBox(label: Text("Label"), content: {
                Text("Content")
            })
            .groupBoxStyle(ColoredGroupBox())
            .padding()
            
            Divider()
            
            Text("Default")
            GroupBox(label: Text("Label"), content: {
                Text("Content")
            })
            .padding()
            Divider()
        }
    }
}

struct TransparentGroupBox: GroupBoxStyle {
    func makeBody(configuration: Configuration) -> some View {
        configuration.content
            .frame(maxWidth: .infinity)
            .padding()
            .background(RoundedRectangle(cornerRadius: 8).fill(Color.blue))
            .overlay(configuration.label.padding(.leading, 4), alignment: .topLeading)
    }
}

struct ColoredGroupBox: GroupBoxStyle {
    func makeBody(configuration: Configuration) -> some View {
        VStack {
            HStack {
                configuration.label
                    .font(.headline)
                Spacer()
            }
            
            configuration.content
        }
        .padding()
        .background(RoundedRectangle(cornerRadius: 8, style: .continuous)
            .fill(.blue)) // Set your color here!!
    }
}

Short answer: it is currently not properly supported by SwiftUI :(

Longer answer: you can create a custom GroupBoxStyle (see example) which will allow you to change the background... but at the cost of having to then manually layout the contents (which somewhat defeats the purpose).

Related