BS
BleepingSwift
Published on

> How to Change the Background Color of a View in SwiftUI

Authors
  • avatar
    Name
    Mick MacCallum
    Twitter
    @0x7fs

Setting a background color is one of the most common tasks in SwiftUI, but there are several approaches depending on what you're trying to achieve. The right method depends on whether you want the background to respect safe areas, fill the entire screen, or adapt to system appearance.

Using the background Modifier

The most straightforward way to add a background color is with the .background() modifier:

Text("Hello, World!")
    .padding()
    .background(Color.blue)

This adds a blue background directly behind the text, sized to match the view's frame including padding. The background doesn't extend beyond the view's bounds.

You can also use semantic colors that adapt to light and dark mode:

Text("Adaptive Background")
    .padding()
    .background(Color(.systemBackground))

The Color(.systemBackground) syntax creates a SwiftUI Color from a UIKit UIColor, giving you access to the full range of system colors.

Filling the Entire Screen

To create a full-screen background, use a ZStack with a color that ignores safe areas:

struct ContentView: View {
    var body: some View {
        ZStack {
            Color.blue
                .ignoresSafeArea()

            Text("Content goes here")
                .foregroundStyle(.white)
        }
    }
}

The color fills edge-to-edge, including under the notch and home indicator, while your content remains within the safe area.

Background with Shape

Combine backgrounds with shapes for rounded corners or other effects:

Text("Rounded Background")
    .padding()
    .background(Color.green, in: RoundedRectangle(cornerRadius: 10))

This syntax, introduced in iOS 15, places the color inside the specified shape. For earlier iOS versions:

Text("Rounded Background")
    .padding()
    .background(
        RoundedRectangle(cornerRadius: 10)
            .fill(Color.green)
    )

Using Gradients

SwiftUI supports linear, radial, and angular gradients as backgrounds:

Text("Gradient Background")
    .frame(maxWidth: .infinity, maxHeight: .infinity)
    .background(
        LinearGradient(
            colors: [.blue, .purple],
            startPoint: .topLeading,
            endPoint: .bottomTrailing
        )
    )
    .ignoresSafeArea()

For a radial gradient emanating from a point:

Circle()
    .frame(width: 200, height: 200)
    .background(
        RadialGradient(
            colors: [.yellow, .orange, .red],
            center: .center,
            startRadius: 0,
            endRadius: 100
        )
    )

Material Backgrounds

iOS 15 introduced materials for translucent, blurred backgrounds that adapt to content behind them:

Text("Frosted Glass Effect")
    .padding()
    .background(.ultraThinMaterial)
    .cornerRadius(10)

Available materials include .ultraThinMaterial, .thinMaterial, .regularMaterial, .thickMaterial, and .ultraThickMaterial, ranging from most to least transparent.

VStack(spacing: 20) {
    Text("Ultra Thin").padding().background(.ultraThinMaterial)
    Text("Regular").padding().background(.regularMaterial)
    Text("Ultra Thick").padding().background(.ultraThickMaterial)
}

Conditional Backgrounds

Change backgrounds based on state:

struct ToggleBackground: View {
    @State private var isActive = false

    var body: some View {
        Text(isActive ? "Active" : "Inactive")
            .padding()
            .background(isActive ? Color.green : Color.gray)
            .cornerRadius(8)
            .onTapGesture {
                withAnimation {
                    isActive.toggle()
                }
            }
    }
}

For complex conditions, compute the color separately:

struct StatusView: View {
    let status: Status

    private var backgroundColor: Color {
        switch status {
        case .success: return .green
        case .warning: return .orange
        case .error: return .red
        case .neutral: return .gray
        }
    }

    var body: some View {
        Text(status.message)
            .padding()
            .background(backgroundColor.opacity(0.2))
            .foregroundStyle(backgroundColor)
            .cornerRadius(8)
    }
}

List and Form Backgrounds

Lists and Forms have their own background styling. To change a List's background:

List {
    Text("Item 1")
    Text("Item 2")
}
.scrollContentBackground(.hidden)
.background(Color.mint)

The .scrollContentBackground(.hidden) modifier removes the default background, letting your custom background show through. This works on iOS 16 and later.

For individual list rows:

List {
    Text("Custom Row")
        .listRowBackground(Color.yellow)
}

Setting a background on a NavigationStack requires similar treatment:

NavigationStack {
    List {
        Text("Content")
    }
    .scrollContentBackground(.hidden)
    .background(
        LinearGradient(
            colors: [.blue.opacity(0.3), .purple.opacity(0.3)],
            startPoint: .top,
            endPoint: .bottom
        )
    )
    .navigationTitle("My App")
}

Background vs Overlay

Don't confuse .background() with .overlay(). Background places content behind the view; overlay places content in front:

Text("Hello")
    .padding(40)
    .background(Color.blue)  // Behind the text
    .overlay(
        Circle()
            .fill(Color.red)
            .frame(width: 20, height: 20),
        alignment: .topTrailing
    )  // In front, positioned at top-trailing

Performance Considerations

For frequently updating views, prefer simple color backgrounds over complex gradients or materials. Materials in particular involve real-time blur calculations that can impact performance in scrolling lists or animations.

If you're building a list with custom row backgrounds, keep them simple:

// Efficient
.listRowBackground(Color.blue.opacity(0.1))

// More expensive
.listRowBackground(
    LinearGradient(colors: [.blue, .purple], startPoint: .leading, endPoint: .trailing)
)

The background modifier is one of SwiftUI's most versatile tools. Start with simple colors, then layer in gradients and materials as your design requires.

subscribe.sh

// Stay Updated

Get notified when I publish new tutorials on Swift, SwiftUI, and iOS development. No spam, unsubscribe anytime.

>

By subscribing, you agree to our Privacy Policy.