DEV Community

Kristaps Grinbergs
Kristaps Grinbergs

Posted on

Background Color with SwiftUI

Once you create a SwiftUI view, it has the default background color. White for light mode and black for dark mode respectively. But how to change it to something different? Let's look into that today.

In this article, we will talk about different techniques that we can use to change the default background for our SwiftUI views.

Using modifier

First approach that comes in mind is using .background() modifier. Sadly Apple hasn't provided documentation for this. It takes in a view that is set as a background for the view we are adding this modifier to.

In this case, we want to change the background color. We can pass in, for instance, Color.gray.

Text("Hello, world!")
  .background(Color.gray)
Enter fullscreen mode Exit fullscreen mode

Text background color

We see that it sets the background color only for the text view. That is how SwiftUI works. We want to set it for the whole screen. We could approach it using VStack, HStack, and a couple of Spacer() views.

VStack {
  Spacer()
  HStack {
    Spacer()
    Text("Test")
    Spacer()
  } 
  Spacer()
}.background(Color.gray)
Enter fullscreen mode Exit fullscreen mode

Text background color not extending safe area

It looks a bit better, but we want to set it for the whole screen, ignoring the safe area. We can do it using .edgesIgnoringSafeArea modifier. Using this modifier, we can tell the SwiftUI layout engine to extend outside the screen's safe area. It takes in a parameter that defines which edges we can expand. In this case, we will pass in .all.

.background(Color.gray.edgesIgnoringSafeArea(.all))
Enter fullscreen mode Exit fullscreen mode

Text background color fullscreen

It looks exactly how we wanted. The issue is that the code is quite cumbersome and has a lot of nesting views and spacers. Let's look at it in another way.

Using ZStack

We could dramatically improve the code readability and complexity is to utilize the ZStack view. Using this view, we can layer multiple views on top of each other. Our approach would be to add the background color and then the content on top of it.

ZStack {
  Color.gray
    .edgesIgnoringSafeArea(.all)

  Text("Hello, world!")
}
Enter fullscreen mode Exit fullscreen mode

The code looks much cleaner now, and we have a gray background and text on top of it. The best part of this approach is that we ignore the safe area only for the background color view. Other views won't extend outside the safe area.

Background color with ZStack

Multiple colors

Now that we know how to change background color to one single color, how about setting it to two colors vertically and horizontally?

We could achieve that by using the approach with ZStack and wrapping colors in a VStack view for vertical alignment or HStack view for vertical alignment.

Vertical alignment

Let's use two colors - gray and black. By wrapping them in VStack view and using ZStack we can split the screen in half vertically. One of them is filled with gray and the other with black color.

ZStack {
  VStack(spacing: 0) {
    Color.gray
    Color.black
  }
  .edgesIgnoringSafeArea(.all)
}
Enter fullscreen mode Exit fullscreen mode

Vertical alignment background colors

Horizontal alignment

By changing the VStack to HStack we can fill the screen horizontally with gray and black colors.

ZStack {
  HStack(spacing: 0) {
    Color.gray
    Color.black
  }
  .edgesIgnoringSafeArea(.all)
}
Enter fullscreen mode Exit fullscreen mode

Horizontal alginment background colors

Chess table background

Let's do something a bit crazy by building a background that would look like a chess table. We can iterate a couple of times the previous example with multiple colors vertically and horizontally.

ZStack {
  VStack(spacing: 0) {
    ForEach((1...10).reversed(), id: \.self) { i in
      HStack(spacing: 0) {
        ForEach((1...5).reversed(), id: \.self) { i in
          Color.gray
          Color.black
        }
      }
      HStack(spacing: 0) {
        ForEach((1...5).reversed(), id: \.self) { i in
          Color.black
          Color.gray
        }
      }
    }
  }.edgesIgnoringSafeArea(.all)
}
Enter fullscreen mode Exit fullscreen mode

Here we see the power of the SwiftUI layout engine and Swift code combined.

Chess table background

TL;DR

SwiftUI views come with default background color - white on light mode and black in dark mode. In many cases, we would like to change it to something else. The first way would be to use the .background modifier and pass Colorwhich is a view in SwiftUI. The second approach would be using ZStack and add one color or multiple colors wrapped in VStack for vertical and HStack for horizontal layout.

If you have other ideas about changing the background color for a SwiftUI view, let me know. Thank you for reading.

Links

Top comments (2)

Collapse
 
domainxh profile image
Xiaoheng Pan

I am using the ZStack approach and was able to address color issues in normal mode for safe areas. However, during rotation, you can see small white edges momentarily as the screen rotates. Any suggestion to address that issue?

Collapse
 
robbertkl profile image
Robbert Klarenbeek

I was struggling with the same issue, but managed to find a solution. Please see my answer on Stack Overflow. Hope that helps :)