SwiftUI - How do I change the background color of a View?
ViewBackgroundBackground ColorModifierSwiftuiView Problem Overview
I'm beginning to try out SwiftUI
and I'm surprised that it doesn't seem to be straightforward to change the background color of a View
. How do you do this using SwiftUI
?
View Solutions
Solution 1 - View
Screen's Background Color
(As of Xcode Version 13)
I'm not sure if the original poster meant the background color of the entire screen or of individual views. So I'll just add this answer which is to set the entire screen's background color.
Using ZStack
var body: some View {
ZStack {
Color.purple
.ignoresSafeArea()
// Your other content here
// Other layers will respect the safe area edges
}
}
I added .ignoresSafeArea()
otherwise, it will stop at safe area margins.
Using Overlay Modifier
var body: some View {
Color.purple
.ignoresSafeArea(.vertical) // Ignore just for the color
.overlay(
VStack(spacing: 20) {
Text("Overlay").font(.largeTitle)
Text("Example").font(.title).foregroundColor(.white)
})
}
Note: It's important to keep the .ignoresSafeArea
on just the color so your main content isn't ignoring the safe area edges too.
iOS 15
iOS 15/Xcode 13 has introduced some changes to the way Styles work with the edges of safe areas.
From my observation, the rule is: If the style touches the safe area edge, it will bleed into the safe area.
This gives you more options for setting a background color/style.
What is a Style?
A Style can be:
- Colors
- Materials (blur effects)
- Hierarchical views (.secondary, .tertiary, .quaternary)
- Gradients
Using Background
Because the background of the VStack
touches the edge of the safe area, the purple color will bleed into the safe area.
var body: some View {
VStack {
Text("Hello, World!")
Divider()
Spacer()
}
.background(Color.purple)
}
TabView
In iOS 15 the TabView is no longer translucent. Meaning the background color will bleed right into it.
If you want to provide a custom style for your TabView, you can add another Style that touches the bottom safe area edge so that bleeds into your TabView. For example:
var body: some View {
TabView {
VStack {
Text("Hello, World!")
Divider()
Spacer()
// Bleeds into TabView
Rectangle()
.frame(height: 0)
.background(.thinMaterial)
}
.background(Color.purple)
.tabItem {
Text("Tab 1")
Image(systemName: "wifi")
}
}
}
NavigationView
The same thing that happens to TabView will also happen with NavigationView.
To customize the NavigationView style, add a style that will touch the top safe area edge and it will bleed into the NavigationView:
var body: some View {
NavigationView {
VStack {
// Bleeds into NavigationView
Rectangle()
.frame(height: 0)
.background(.ultraThinMaterial)
Text("Hello, World!")
Divider()
Spacer()
}
.background(Color.purple)
.navigationTitle(Text("Style"))
}
}
I'm totally open to other ways of accomplishing this. Leave a comment or edit this answer if you know of other ways.
Solution 2 - View
You can do something like:
.background(Color.black)
around your view.
eg. from the default template (I am encompassing it around a Group):
var body: some View {
VStack {
Text("Hello SwiftUI!")
}
.background(Color.black)
}
To add some opacity to it, you can add the .opacity
method as well:
.background(Color.black.opacity(0.5))
You can also make use of the inspect element of the view by CMD + click on the View and clicking Show SwiftUI Inspector
> Background
> Your Color
Solution 3 - View
Fill the entire screen:
var body: some View {
Color.green.edgesIgnoringSafeArea(.all)
}
Code | Result |
---|---|
https://i.stack.imgur.com/7qwxR.png" width="300" alt="Image of code"> |
Solution 4 - View
like this
struct ContentView : View {
@State var fullName: String = "yushuyi"
var body: some View {
VStack
{
TextField($fullName).background(SwiftUI.Color.red)
Spacer()
}.background(SwiftUI.Color.yellow.edgesIgnoringSafeArea(.all))
}
}
Solution 5 - View
List
:
For All SwiftUI's List
s are backed by a UITableView
in iOS. so you need to change the background color of the tableView. But since Color
and UIColor
values are slightly different, you can get rid of the UIColor
.
struct ContentView : View {
init(){
UITableView.appearance().backgroundColor = .clear
}
var body: some View {
List {
Section(header: Text("First Section")) {
Text("First Cell")
}
Section(header: Text("Second Section")) {
Text("First Cell")
}
}
.background(Color.yellow)
}
}
Now you can use Any background (including all Color
s) you want
Also First look at this result:
As you can see, you can set the color of each element in the View hierarchy like this:
struct ContentView: View {
init(){
UINavigationBar.appearance().backgroundColor = .green
//For other NavigationBar changes, look here:(https://stackoverflow.com/a/57509555/5623035)
}
var body: some View {
ZStack {
Color.yellow
NavigationView {
ZStack {
Color.blue
Text("Some text")
}
}.background(Color.red)
}
}
}
And the first one is window
:
window.backgroundColor = .magenta
The very common issue is we can not remove the background color of SwiftUI's HostingViewController
(yet), so we can't see some of the views like navigationView
through the views hierarchy. You should wait for the API or try to fake those views (not recommended).
Solution 6 - View
struct Soview: View {
var body: some View {
VStack{
Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/)
.frame(maxWidth:.infinity,maxHeight: .infinity)
}.background(Color.yellow).ignoresSafeArea(.all)
}
}
Solution 7 - View
Several possibilities : (SwiftUI / Xcode 11)
1 .background(Color.black) //for system colors
2 .background(Color("green")) //for colors you created in Assets.xcassets
- Otherwise you can do Command+Click on the element and change it from there.
Hope it help :)
Solution 8 - View
You can Simply Change Background Color of a View:
var body : some View{
VStack{
Color.blue.edgesIgnoringSafeArea(.all)
}
}
and You can also use ZStack :
var body : some View{
ZStack{
Color.blue.edgesIgnoringSafeArea(.all)
}
}
Solution 9 - View
Would this solution work?:
add following line to SceneDelegate: window.rootViewController?.view.backgroundColor = .black
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
if let windowScene = scene as? UIWindowScene {
window.rootViewController?.view.backgroundColor = .black
}
Solution 10 - View
I like to declare a modifier for changing the background color of a view.
extension View {
func background(with color: Color) -> some View {
background(GeometryReader { geometry in
Rectangle().path(in: geometry.frame(in: .local)).foregroundColor(color)
})
}
}
Then I use the modifier by passing in a color to a view.
struct Content: View {
var body: some View {
Text("Foreground Label").foregroundColor(.green).background(with: .black)
}
}
Solution 11 - View
Xcode 11.5
Simply use ZStack to add background color or images to your main view in SwiftUI
struct ContentView: View {
var body: some View {
ZStack {
Color.black
}
.edgesIgnoringSafeArea(.vertical)
}
}
Solution 12 - View
Use Below Code for Navigation Bar Color Customization
struct ContentView: View {
@State var msg = "Hello SwiftUI😊"
init() {
UINavigationBar.appearance().backgroundColor = .systemPink
UINavigationBar.appearance().largeTitleTextAttributes = [
.foregroundColor: UIColor.white,
.font : UIFont(name:"Helvetica Neue", size: 40)!]
// 3.
UINavigationBar.appearance().titleTextAttributes = [
.font : UIFont(name: "HelveticaNeue-Thin", size: 20)!]
}
var body: some View {
NavigationView {
Text(msg)
.navigationBarTitle(Text("NAVIGATION BAR"))
}
}
}
Solution 13 - View
NavigationView Example:
var body: some View {
var body: some View {
NavigationView {
ZStack {
// Background
Color.blue.edgesIgnoringSafeArea(.all)
content
}
//.navigationTitle(Constants.navigationTitle)
//.navigationBarItems(leading: cancelButton, trailing: doneButton)
//.navigationViewStyle(StackNavigationViewStyle())
}
}
}
var content: some View {
// your content here; List, VStack etc - whatever you want
VStack {
Text("Hello World")
}
}
Solution 14 - View
To make a central/reusable background widget, you can do something like this -
import SwiftUI
struct BgView<Content>: View where Content: View {
private let content: Content
public init(@ViewBuilder content: () -> Content) {
self.content = content()
}
var body : some View {
ZStack {
Color.black.ignoresSafeArea()
content
}
}
}
And can easily use in all of your views like below -
import SwiftUI
struct TestView: View {
var body: some View {
BgView{
Text("Hello, World!")
}.foregroundColor(.white)
}
}
struct TestView_Previews: PreviewProvider {
static var previews: some View {
TestView()
}
}
Solution 15 - View
The code on Scene delegate in Swift UI
Content view background-color
> window.rootViewController?.view.backgroundColor = .lightGray