How to hide the status bar in SwiftUI
Asked Answered
D

6

14

I want to hide the status bar in SwiftUI. I have try the method "statusBar(hidden: true)", but it doesn't work. Is there any solution to make it in SwiftUI.

the demo code as below:

var body: some View {
        VStack {
            Text("Hello World")

        }
        .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
        .background(Color.blue)
        .edgesIgnoringSafeArea(.all)
        .statusBar(hidden: true)

    }
Dished answered 5/7, 2019 at 4:50 Comment(0)
H
24
.edgesIgnoringSafeArea(.all)
.statusBar(hidden: true)

try this

Harrisonharrod answered 30/8, 2019 at 12:53 Comment(3)
If using a NavigationView, I find setting this on the top level NavigationView block works best. You don't need to redeclare this on lower level screens.Zoogeography
Great answer, interesting that without .edgesIgnoringSafeArea(.all) it's not hidingCharged
this seems to be broken in iOS 14...no matter what I do I can't get statusBar hidden to work on a screen with a navigation viewSerrate
S
10

iOS 14, SwiftUI

I found out, that the most effective way in iOS14 is an entry into the info.plist. However, this method works all the time, which means that if you want to return the statusBar at the click of a  UIButton, then this method is not suitable for you.

For me it worked for the whole app, no matter if an instance of NavigationView is used or not.

Open your Info.plist "as Source Code" (see image below)and paste that four lines into it:

<key>UIStatusBarHidden</key>
<true/>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>

enter image description here

Swacked answered 18/2, 2021 at 21:27 Comment(0)
P
7

There are a few different ways you can hide the status bar in a SwiftUI project depending on your intentions. I’ve listed a few in no particular order. All the examples work with iOS 13 & iOS 14 using Xcode 11 & Xcode 12 with the exception of OPTION-2.

OPTION-1
In your info.plist file make sure you have these settings:

<key>UIStatusBarHidden</key>
<true/>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>

Add the following UIViewController extension

extension UIViewController {
    func prefersStatusBarHidden() -> Bool {
        return true
    }
}

OPTION-2 (iOS 14 & Xcode 12 Only)
In your info.plist file make sure you have these settings:

<key>UIStatusBarHidden</key>
<true/>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>

Add an AppDelegate to a SwiftUI app as described in this link but add the the line noted below. https://www.hackingwithswift.com/quick-start/swiftui/how-to-add-an-appdelegate-to-a-swiftui-app

class AppDelegate: NSObject, UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        UIApplication.shared.isStatusBarHidden = true // <== ADD THIS LINE
        return true
    }
}

Note you’ll get a deprecated call warning, but it should still work.

OPTION-3
In your info.plist file make sure you have these settings:

<key>UIStatusBarHidden</key>
<true/>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>

Make sure your initial SwiftUI View is a Navigation view where you hide the status bar. Then if you navigate to a tab bar view or any subsequent views the status bar will be hidden.

struct ContentView: View {
    var body: some View {
        NavigationView {
            NavigationLink(destination: MyTabView()) {
                Text("Go To Tabview")
            }
        }
        .edgesIgnoringSafeArea(.all)
        .statusBar(hidden: true)
    }
}

struct MyTabView: View {
    var body: some View {
        TabView {
            TabView1().tabItem {
                Text("Tab 1")
            }

            TabView2().tabItem {
                Text("Tab 2")
            }
        }
    }
}

struct TabView1: View {
    var body: some View {
        Text("Tab View 1")
    }
}

struct TabView2: View {
    var body: some View {
        Text("Tab View 2")
    }
}

OPTION-4
Use UIStatusBarManager https://developer.apple.com/documentation/uikit/uistatusbarmanager

Picardi answered 16/11, 2020 at 4:50 Comment(2)
Confirmed OPTION-3 worked for me like a charm. On SwiftUI Lifecycle app. Xcode 12 + iOS 14Vacuole
You cannot update the status bar with UIStatusBarManager, is isStatusBarHidden is getter only.Trim
B
0

The issue is finally solved with Xcode 13.0 beta 3 - you can attach the statusBarHidden modifier to both a TabView and a NavigationView and the status bar hides as expected.

Bon answered 23/7, 2021 at 2:17 Comment(0)
S
0

I found the only way to get this to work per view is to wrap your rootView in a HostingController like:

class HostingController<ContentView>: UIHostingController<ContentView> where ContentView : View {

    

    init(view: ContentView) {

        super.init(rootView: view)



        NotificationCenter.default.addObserver(forName: .onDarkStatusBar, object: nil, queue: .main) { _ in

            self.statusBarEnterDarkBackground()

        }

        

        NotificationCenter.default.addObserver(forName: .onLightStatusBar, object: nil, queue: .main) { _ in

            self.statusBarEnterLightBackground()

        }

        

        NotificationCenter.default.addObserver(forName: .onShowStatusBar, object: nil, queue: .main) { _ in

            self.statusBarShow()

        }

        

        NotificationCenter.default.addObserver(forName: .onHideStatusBar, object: nil, queue: .main) { _ in

            self.statusBarHide()

        }

    }

    

    @objc required dynamic init?(coder aDecoder: NSCoder) {

        fatalError("init(coder:) has not been implemented")

    }

    

    private var isDarkContentBackground = false

    private var isStatusBarHiden = false



    func statusBarEnterDarkBackground() {

        isDarkContentBackground = false

        setNeedsStatusBarAppearanceUpdate()

    }



    func statusBarEnterLightBackground() {

        isDarkContentBackground = true

        setNeedsStatusBarAppearanceUpdate()

    }

    

    func statusBarHide() {

        isStatusBarHiden = true

        setNeedsStatusBarAppearanceUpdate()

    }



    func statusBarShow() {

        isStatusBarHiden = false

        setNeedsStatusBarAppearanceUpdate()

    }



    override var preferredStatusBarStyle: UIStatusBarStyle {

        if isDarkContentBackground {

            return .lightContent

        }

        else

        {

            return .darkContent

        }

    }

    

    override var prefersStatusBarHidden: Bool {

      return isStatusBarHiden

    }



}

Use as

let window = UIWindow(windowScene: windowScene)

            window.rootViewController = HostingController(view: contentView)

Then send out a notification from onDissapear and onAppear.

extension Notification.Name {

   static let onDarkStatusBar = Notification.Name("onDarkStatusBar")

    static let onLightStatusBar = Notification.Name("onLightStatusBar")

    static let onHideStatusBar = Notification.Name("onHideStatusBar")

    static let onShowStatusBar = Notification.Name("onShowStatusBar")

}

Using

                            .onAppear {

                                NotificationCenter.default.post(name: Notification.Name.onHideStatusBar, object: nil)

                            }

                            .onDisappear {

                                NotificationCenter.default.post(name: Notification.Name.onShowStatusBar, object: nil)

                            }
Sayette answered 5/8, 2021 at 15:43 Comment(0)
N
0

I didn't see anybody answer this here in the way I solved this problem so here's my two cents:

Looks like you can just set a key in your info.plist to Status bar is initially hidden and the value of that key to YES (it defaults to no).

The xml for your plist (what you get if you right click it and select Open as > Source Code) would have an entry like this:

<key>UIStatusBarHidden</key>
<true/>

I didn't need to add any other keys.

This solved my problem because, initially, I (similar to you) was just doing this:

var body: some View {
        VStack {
            Text("Hello World")

        }
        .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
        .background(Color.blue)
        .edgesIgnoringSafeArea(.all)
        .statusBar(hidden: true)

    }

And although it removed the status bar from my views, it still showed up briefly on launch. After adding this key, the status bar no longer showed up at launch nor did it show up for any of my views.

In short and to reiterate, all you need is to add the plist key and to use the x.statusBar(hidden: true) modifier in the view hierarchy where we want its effect.

Nagual answered 15/10, 2023 at 21:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.