How to change the status bar background color in SwiftUI?
ZStack {
...
}
.edgesIgnoringSafeArea(.vertical) // or .top
SwiftUI: Set Status Bar Color For a Specific View
Status bar content color can be modified per view controller based, but SwiftUI uses, most usually, only one view controller, root hosting view controller. So it needs to push that root controller to change preferredStatusBarStyle
property, which in base class is read-only.
So the idea is to override default UIHostingController
to have possibility change that preferredStatusBarStyle
value and use custom Environment
value so any internal SwiftUI subview can modify that preferred content style.
Here is approach, scratchy, (it is assumed that target Info.plist is configured appropriately)
class LocalStatusBarStyle { // style proxy to be stored in Environment
fileprivate var getter: () -> UIStatusBarStyle = { .default }
fileprivate var setter: (UIStatusBarStyle) -> Void = {_ in}
var currentStyle: UIStatusBarStyle {
get { self.getter() }
set { self.setter(newValue) }
}
}
// Custom Environment key, as it is set once, it can be accessed from anywhere
// of SwiftUI view hierarchy
struct LocalStatusBarStyleKey: EnvironmentKey {
static let defaultValue: LocalStatusBarStyle = LocalStatusBarStyle()
}
extension EnvironmentValues { // Environment key path variable
var localStatusBarStyle: LocalStatusBarStyle {
get {
return self[LocalStatusBarStyleKey.self]
}
}
}
// Custom hosting controller that update status bar style
class MyHostingController<Content>: UIHostingController<Content> where Content: View {
private var internalStyle = UIStatusBarStyle.default
@objc override dynamic open var preferredStatusBarStyle: UIStatusBarStyle {
get {
internalStyle
}
set {
internalStyle = newValue
self.setNeedsStatusBarAppearanceUpdate()
}
}
override init(rootView: Content) {
super.init(rootView:rootView)
LocalStatusBarStyleKey.defaultValue.getter = { self.preferredStatusBarStyle }
LocalStatusBarStyleKey.defaultValue.setter = { self.preferredStatusBarStyle = $0 }
}
@objc required dynamic init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
Usage..
- somewhere in scene delegate
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// ...
window.rootViewController = MyHostingController(rootView: contentView)
- somewhere in content view
struct ContentView: View {
@Environment(\.localStatusBarStyle) var statusBarStyle
...
var body: some View {
ZStack {
....
NavigationView {
NavigationLink(destination: ...) {
...
}
.onAppear {
self.statusBarStyle.currentStyle = .lightContent
}
.onDisappear {
self.statusBarStyle.currentStyle = .default
}
}
}
}
}
How to change Status Bar text color in iOS
Set the
UIViewControllerBasedStatusBarAppearance
toYES
in the .plist file.In the
viewDidLoad
do a[self setNeedsStatusBarAppearanceUpdate];
Add the following method:
- (UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleLightContent;
}
Note: This does not work for controllers inside UINavigationController
, please see Tyson's comment below :)
Swift 3 - This will work controllers inside UINavigationController
. Add this code inside your controller.
// Preferred status bar style lightContent to use on dark background.
// Swift 3
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
Swift 5 and SwiftUI
For SwiftUI create a new swift file called HostingController.swift
import Foundation
import UIKit
import SwiftUI
class HostingController: UIHostingController<ContentView> {
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
}
Then change the following lines of code in the SceneDelegate.swift
window.rootViewController = UIHostingController(rootView: ContentView())
to
window.rootViewController = HostingController(rootView: ContentView())
Related Topics
Table View Images Never Being Released
Xcode Canvas for Swiftui Previews Does Not Show Up
Nstimer Timerwithtimeinterval: Not Working
Generate Random Numbers with a Given Distribution
Sharing Code Between Original iOS App and App Extension
How to Disable Caching in Alamofire
iOS Simulator Games Run Very Slow (Low Fps)
How to Detect When Avplayer Video Ends Playing
Nsfetchedresultscontroller V.S. Uilocalizedindexedcollation
How to Stop Multiple Times Method Calling of Didupdatelocations() in iOS
Cannot Put a Google Maps Gmsmapview in a Subview of Main Main View
Storing Asynchronous Cloud Firestore Query Results in Swift
Calayer with Transparent Hole in It
What Does "@Private" Mean in Objective-C
Uinavigationcontroller "Back Button" Custom Text
Why Calling Setneedsupdateconstraints Isn't Needed for Constraint Changes or Animations