Reputation: 173
Thanks for taking your time to help others.
This is the original post, I publish here also hoping for better luck. Thanks!
Our SwiftUI app min deployment is iOS 14. We've been struggling with status bar color just in iOS 16.
We can't change its color/appearance from light to dark.
Since now we used to manage the appearance with ...
1- Call in specific view, when a condition is given, like no dark mode supported, or side menu have been open
UIApplication.setStatusBarStyle(.darkContent)
2- The extension to support this on any SwiftUI View
import UIKit
extension UIApplication {
class func setStatusBarStyle(_ style: UIStatusBarStyle) {
if let controller = UIApplication.getKeyWindow()?.rootViewController as? ContentHostingController {
controller.changeStatusBarStyle(style)
}
}
}
3- Actually, the controller class
import SwiftUI
import UIKit
class ContentHostingController: UIHostingController<AnyView> {
private var currentStatusBarStyle: UIStatusBarStyle = .default
override var preferredStatusBarStyle: UIStatusBarStyle {
currentStatusBarStyle
}
func changeStatusBarStyle(_ style: UIStatusBarStyle) {
self.currentStatusBarStyle = style
self.setNeedsStatusBarAppearanceUpdate()
}
}
But, as I said, this stopped working with iOS 16.
As we googled it...
First, a View extension to keep it clean:
func iOS16navBarAdapter(_ colorScheme: ColorScheme) -> some View {
if #available(iOS 16, *) {
return self
.toolbarBackground(Color.navigationBar, for: .navigationBar)
.toolbarBackground(.visible, for: .navigationBar)
.toolbarColorScheme(colorScheme, for: .navigationBar)
} else {
return self
}
}
You can use as follows on your view:
@State private var iOS16colorScheme: ColorScheme = .dark
...
VStack {
...
}
.iOS16navBarAdapter(iOS16colorScheme)
.onChange(of: globalSideMenu.xCoord) { value in
iOS16colorScheme = value > sideMenuOffset ? .light : .dark
}
Upvotes: 7
Views: 4035
Reputation: 53111
There are a couple of ways to change the status bar colour.
Starting with this View
:
struct ContentView: View {
var body: some View {
ZStack {
Color.mint
.ignoresSafeArea()
Text("Hello")
}
}
}
and setting the following info.plist keys:
View controller-based status bar appearance: NO
Status bar style: Dark Content
gives:
Changing
gives:
You can also change the status bar text colour on a per view basis, making sure you set
then wrapping your view in a NavigationStack
, and adding the following toolbar
modifiers:
.toolbarBackground(.mint, for: .navigationBar)
.toolbarBackground(.visible, for: .navigationBar)
.toolbarColorScheme(<colorScheme>, for: .navigationBar)
for example:
struct ContentView: View {
var body: some View {
NavigationStack {
TestView(colorScheme: .dark)
}
}
}
struct TestView: View {
let colorScheme: ColorScheme
var body: some View {
ZStack {
Color.mint
.ignoresSafeArea()
VStack {
Text("Hello")
NavigationLink("Push") {
TestView(colorScheme: .dark)
}
}
}
.toolbarBackground(.mint, for: .navigationBar)
.toolbarBackground(.visible, for: .navigationBar)
.toolbarColorScheme(colorScheme, for: .navigationBar)
}
}
gives:
Upvotes: 5