簡體   English   中英

SwiftUI:為特定視圖設置狀態欄顏色

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

我一直在嘗試為我的應用程序的狀態欄顏色設置一個視圖。

我已經嘗試過此處列出的解決方案..“ 如何在 iOS 中更改狀態欄文本顏色”,但這為整個應用程序設置了它。

我想要的是狀態欄顏色為在 SceneDelegate.swift 中設置的 rootViewController 設置白色文本,然后為所有其他視圖默認設置(根據暗模式從白色更改為黑色)。

有任何想法嗎?

狀態欄內容的顏色可以根據每個視圖控制器進行修改,但 SwiftUI 通常只使用一個視圖控制器,即根托管視圖控制器。 因此,它需要推動該根控制器來更改preferredStatusBarStyle屬性,該屬性在基類中是只讀的。

所以想法是覆蓋默認UIHostingController以有可能更改preferredStatusBarStyle狀態欄樣式值並使用自定義Environment值,以便任何內部 SwiftUI 子視圖都可以修改首選內容樣式。

這是方法,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)
    }
}

用法..

  1. 場景委托中的某處
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
//  ...
  window.rootViewController = MyHostingController(rootView: contentView)
  1. 內容視圖中的某處
   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
                     }
                }
            }
        }
    }

備份

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM