Status Bar Background Color in SwiftUI
In iOS 15 it looks like the status bar default is now to have a transparent background. If you don't like this here is how you can change it.
We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track
With the status bar now having a default transparent background in iOS 15, your application might look odd. These types of changes are going to happen as apple evolves the UI, but it would be nice to know how do I change it back to an opaque background.
This is one solution to the problem. If you are building an application in SwiftUI and just need to have it work for a single screen where you might have some content scrolling underneath then you do the following.
• Build a ViewModifier with some attributes.
• Assign it to the view you want to modify
• Done
The following code shows you how the ViewModifer
can be constructed with some initial properties for backgroundColor
and textColor
. We are creating this ViewModifier
as a reusable modifier that you can apply to any view.
struct NavigationBarModifier: ViewModifier {
var backgroundColor: UIColor
var textColor: UIColor
init(backgroundColor: UIColor, textColor: UIColor) {
// assign
self.backgroundColor = backgroundColor
self.textColor = textColor
// configure
let coloredAppearance = UINavigationBarAppearance()
coloredAppearance.configureWithTransparentBackground()
coloredAppearance.backgroundColor = .clear
coloredAppearance.titleTextAttributes = [.foregroundColor: textColor]
coloredAppearance.largeTitleTextAttributes = [.foregroundColor: textColor]
// change appearance
UINavigationBar.appearance().standardAppearance = coloredAppearance
UINavigationBar.appearance().compactAppearance = coloredAppearance
UINavigationBar.appearance().scrollEdgeAppearance = coloredAppearance
UINavigationBar.appearance().tintColor = textColor
}
func body(content: Content) -> some View {
ZStack{
content
VStack {
GeometryReader { geometry in
Color(backgroundColor) // This is Color so we can reference frame
.frame(height: geometry.safeAreaInsets.top)
.edgesIgnoringSafeArea(.top)
Spacer()
}
}
}
}
}
Go to your main view or any view that you want to modify and try it out. Created a property called statusBarModifier
and assigned the background color and text color. Then I wrapped a VStack
within the body
of my view and assigned a .modifier
where I passed in the statusBarModifier
we created. The status bar background color should be red and the text color should be white in your preview.
struct ContentView: View {
let statusBarModifier = NavigationBarModifier(backgroundColor: .red, textColor: .white)
var body: some View {
VStack(spacing: 0) {
Text("Hello, world!")
.padding()
}.modifier(statusBarModifier)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
I don’t know if this is the ideal solution. In my situation I only had a 2 screens that needed to be modified. The source material for this post came from this article. If you go to that article you can get additional instructions on you can extend this view and apply it globally to all your views.