【问题标题】:SwiftUI setting status bar styleSwiftUI 设置状态栏样式
【发布时间】:2019-09-29 09:07:15
【问题描述】:

我一直在尝试将 SwiftUI 应用程序中的状态栏设置为浅色文本,因为它有深色背景。

我在几个网站上找到了这个解决方案,但无法让它发挥作用。

HostingController.swift

import Foundation
import UIKit
import SwiftUI

class HostingController : UIHostingController {
    override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
    }
}

这会在类声明行 Reference to generic type 'UIHostingController' requires arguments in <...> 上返回错误,并建议修复 Insert '<<#Content: View#>>'。应用上述修复会导致错误Use of undeclared type '<#Content: View#>'

然后您需要更改SceneDelegate.swift 文件中的window.rootViewController

SceneDelegate.swift

...

// Create the SwiftUI view that provides the window contents.
        let contentView = Login()

        // Use a UIHostingController as window root view controller.
        if let windowScene = scene as? UIWindowScene {
            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = HostingController(rootView: contentView)
            self.window = window
            window.makeKeyAndVisible()
        }

...

这会在window.rootViewControllerArgument passed to call that takes no arguments 上引发错误

有人有什么想法吗?设置状态栏颜色似乎很麻烦,我认为这是一个相当普遍的要求。

【问题讨论】:

    标签: ios swift swiftui ios13 xcode11


    【解决方案1】:

    您的 HostingController 需要具体类型的 rootView:

    class HostingViewController: UIHostingController<AnyView> {
    
        @objc override var preferredStatusBarStyle: UIStatusBarStyle {
            return .lightContent
        }
    }
    

    然后在func scene(_ scene: UIScene, willConnectTo...中使用它作为rootViewController:

    let contentView = ContentView()
        if let windowScene = scene as? UIWindowScene {
            let window = UIWindow(windowScene: windowScene)
    
            window.rootViewController = HostingViewController(rootView: AnyView(contentView.environmentObject(SessionStore())))
            self.window = window
            window.makeKeyAndVisible()
        }
    

    很遗憾,您不会在画布上看到任何差异,但请在模拟器上尝试一下。

    【讨论】:

    • 谢谢。这行得通。但是我必须删除我的environmentObject 才能使其工作HostingController(rootView: contentView.environmentObject(SessionStore()) 否则它需要修复到HostingController(rootView: contentView.environmentObject(SessionStore()) as! ContentView),然后在运行时抛出SIGABRT 错误。
    • 尝试这样声明: HostingViewController: UIHostingController 然后将你的 rootview 擦除到 AnyView HostingController(rootView: AnyView(contentView.environmentObject(SessionStore())))
    • window.rootViewController = AnyView HostingController(rootView: AnyView(contentView.environmentObject(SessionStore()))) 抛出错误Cannot assign value of type 'AnyView.Type' to type 'UIViewController?'
    • 这不是我的想法。请查看我编辑的答案。
    • 像魅力一样工作window.rootViewController = HostingController(rootView: AnyView(contentView.environmentObject(SessionStore())))
    【解决方案2】:

    另一种扩展UIHostingController 的方法是保留通用的Content 类型,这样就不必传递会话存储:

    class HostingController<Content>: UIHostingController<Content> where Content: View {
        @objc override var preferredStatusBarStyle: UIStatusBarStyle {
            return .lightContent
        }
    }
    

    然后在您的场景委托中:

    window.rootViewController = HostingController(rootView: contentView)
    

    【讨论】:

    • 这很棒。我的问题是一些:除非泛型如上所述,否则 View 和 onTapGesture 将不起作用。我也不需要@objc。其中让我也这样做:``` if let windowScene = scene as? UIWindowScene { let window = UIWindow(windowScene: windowScene) window.rootViewController = HostingController( rootView: homeView.onTapGesture { window.endEditing(true) } ) self.window = window window.makeKeyAndVisible() } ```
    【解决方案3】:

    在 iOS 14 中,您只需在 Info.plist 中更改/添加 2 个键:

    【讨论】:

    • 这是从 iOS 14 开始的正确答案。不再需要对此进行编码。按照上述Info.plist 文件中的说明更改设置。
    • 这里有一段视频展示了如何更新 Info.plist:youtu.be/w-I5I8POMSI
    【解决方案4】:

    我来晚了,但你可以更好地使用泛型:

    class HostingController<ContentView: View>: UIHostingController<ContentView> {
        override var preferredStatusBarStyle: UIStatusBarStyle {
            return .darkContent
        }
    }
    

    这允许您将任何视图传递给 HostingController,即使使用 .environmentObject() 视图修饰符。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-09
      • 1970-01-01
      • 1970-01-01
      • 2016-01-15
      • 2020-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多