简体   繁体   English

SwiftUI:为特定视图设置状态栏颜色

[英]SwiftUI: Set Status Bar Color For a Specific View

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.我已经尝试过此处列出的解决方案..“ 如何在 iOS 中更改状态栏文本颜色”,但这为整个应用程序设置了它。

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

any ideas?有任何想法吗?

Status bar content color can be modified per view controller based, but SwiftUI uses, most usually, only one view controller, root hosting view controller.状态栏内容的颜色可以根据每个视图控制器进行修改,但 SwiftUI 通常只使用一个视图控制器,即根托管视图控制器。 So it needs to push that root controller to change preferredStatusBarStyle property, which in base class is read-only.因此,它需要推动该根控制器来更改preferredStatusBarStyle属性,该属性在基类中是只读的。

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.所以想法是覆盖默认UIHostingController以有可能更改preferredStatusBarStyle状态栏样式值并使用自定义Environment值,以便任何内部 SwiftUI 子视图都可以修改首选内容样式。

Here is approach, scratchy, (it is assumed that target Info.plist is configured appropriately)这是方法,scratchy,(假设目标 Info.plist 配置正确)

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..用法..

  1. somewhere in scene delegate场景委托中的某处
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
//  ...
  window.rootViewController = MyHostingController(rootView: contentView)
  1. 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
                     }
                }
            }
        }
    }

backup 备份

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM