SwiftUI:为特定视图设置状态栏颜色 [英] SwiftUI: Set Status Bar Color For a Specific View

查看:378
本文介绍了SwiftUI:为特定视图设置状态栏颜色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直试图为单个视图设置应用程序的状态栏颜色.

i have been trying to set the status bar colour of my application for just a single view.

我已经尝试了此处列出的解决方案.'

i have tried the solution listed here..'How to change Status Bar text color in iOS' but that sets it for the whole application.

我想要的是状态栏颜色,以便在SceneDelegate.swift中为rootViewController设置白色文本,然后为所有其他视图默认设置(根据暗模式从白色更改为黑色).

What i want is the status bar colour to have white text for the rootViewController set in SceneDelegate.swift and then be defaulted (change from white to black depending on dark mode) for all other views.

有什么想法吗?

推荐答案

状态栏内容颜色可以基于每个视图控制器进行修改,但是SwiftUI通常仅使用一个视图控制器,即根托管视图控制器.因此,它需要推动该根控制器来更改preferredStatusBarStyle属性,该属性在基类中是只读的.

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.

因此,其想法是覆盖默认的UIHostingController,以更改preferredStatusBarStyle值并使用自定义的Environment值,以便任何内部SwiftUI子视图都可以修改该首选内容样式.

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.

这是方法,草率的(假设目标Info.plist配置正确)

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)
    }
}

用法..

1)场景委托中的某个地方

1) somewhere in scene delegate

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        ...
        window.rootViewController = MyHostingController(rootView: contentView)

2)在内容视图中的某处

2) 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
                 }
            }
        }
    }
}

这篇关于SwiftUI:为特定视图设置状态栏颜色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆