如何在SwiftUI中隐藏状态栏

10
我想在SwiftUI中隐藏状态栏。我尝试了"statusBar(hidden: true)"的方法,但它不起作用。是否有任何解决方案可在SwiftUI中实现?
以下是演示代码:
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)

    }
6个回答

21
.edgesIgnoringSafeArea(.all)
.statusBar(hidden: true)
尝试这个。

如果使用NavigationView,我发现将其设置在顶层NavigationView块上效果最佳。您不需要在较低级别的屏幕上重新声明此内容。 - Ryan
很棒的答案,有趣的是如果没有使用.edgesIgnoringSafeArea(.all)它就不会隐藏。 - sig
22
似乎在iOS 14上出现了问题......无论我做什么,都无法使状态栏在具有导航视图的屏幕上隐藏。 - Timmerz

7

iOS 14,SwiftUI

我发现,在iOS14中最有效的方法是在info.plist中进行设置。然而,这种方法一直起作用,这意味着如果你想在点击UIButton时返回statusBar,则此方法不适合您。

对我来说,它为整个应用程序工作,无论是否使用NavigationView实例。

打开您的Info.plist文件,并将以下四行粘贴到其中(请参见下面的图片,以“源代码”形式打开):

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

enter image description here


7

根据您的意图,您可以有几种不同的方法在SwiftUI项目中隐藏状态栏。我列出了一些没有特定顺序的例子。除了OPTION-2,所有示例都适用于使用Xcode 11和Xcode 12的iOS 13和iOS 14。

选项1:
在info.plist文件中确保您具有以下设置:

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

添加以下 UIViewController 扩展
extension UIViewController {
    func prefersStatusBarHidden() -> Bool {
        return true
    }
}

选项2(仅适用于iOS 14和Xcode 12)
在您的info.plist文件中,请确保设置如下:

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

按照此链接中描述的方法,将AppDelegate添加到SwiftUI应用程序中,但添加下面标注的行。 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
    }
}

请注意,你将会收到一个弃用调用警告,但它仍然可以工作。

选项三
在你的 info.plist 文件中,确保以下设置:

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

确保您的初始SwiftUI视图是一个导航视图,其中隐藏状态栏。然后,如果您导航到一个选项卡栏视图或任何后续视图,则状态栏将被隐藏。

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
使用UIStatusBarManager https://developer.apple.com/documentation/uikit/uistatusbarmanager


确认在SwiftUI生命周期应用程序中,OPTION-3像魔法一样完美地运行。使用Xcode 12 + iOS 14。 - Legolas Wang
1
您无法使用 UIStatusBarManager 更新状态栏,因为 isStatusBarHidden 只能获取。 - pierre23

0
我发现每个视图都能让它工作的唯一方法是将你的rootView包装在一个HostingController中,像这样:
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

    }



}

用作

let window = UIWindow(windowScene: windowScene)

            window.rootViewController = HostingController(view: contentView)

然后从 onDissapear 和 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")

}

使用
                            .onAppear {

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

                            }

                            .onDisappear {

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

                            }

0
问题终于在Xcode 13.0 beta 3中得到解决 - 您可以将statusBarHidden修饰符附加到TabView和NavigationView上,状态栏会按预期隐藏。

0

我在这里没有看到任何人以我解决这个问题的方式回答,所以这是我的两分钱:

看起来你可以在你的info.plist中设置一个键Status bar is initially hidden,并将该键的值设置为YES(默认为no)。

你的plist的xml(如果你右键点击它并选择Open as > Source Code)会有一个类似这样的条目:

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

我不需要添加其他的键。
这解决了我的问题,因为最初,我(和你一样)只是这样做:
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)

    }

尽管它从我的视图中移除了状态栏,但在启动时仍会短暂地显示出来。添加了这个键之后,状态栏在启动时不再显示,也不会在任何视图中显示出来。
简而言之,你只需要添加 plist 键,并在视图层次结构中使用 x.statusBar(hidden: true) 修饰符,就可以实现效果。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接