我现在可以自己解决了。我找到了一个方法,可以处理与TabViews相关的问题,基于:
https://github.com/xavierdonnellon/swiftui-statusbarstyle
我的完整代码示例,其中保存和恢复了先前状态栏样式的状态(在运行时保持对状态栏样式层次结构的关注非常重要):
ExampleApp.swift
import SwiftUI
@main
struct ExampleApp: App {
init() {
let coloredNavAppearance = UINavigationBarAppearance()
coloredNavAppearance.configureWithTransparentBackground()
coloredNavAppearance.backgroundColor = .clear
coloredNavAppearance.backgroundEffect = nil
coloredNavAppearance.backgroundImage = UIImage()
coloredNavAppearance.shadowImage = UIImage()
coloredNavAppearance.shadowColor = .clear
coloredNavAppearance.titleTextAttributes = [
.foregroundColor: UIColor.black
]
coloredNavAppearance.largeTitleTextAttributes = [
.foregroundColor: UIColor.black
]
UINavigationBar.appearance().standardAppearance = coloredNavAppearance
UINavigationBar.appearance().scrollEdgeAppearance = coloredNavAppearance
UINavigationBar.appearance().compactAppearance = coloredNavAppearance
}
var body: some Scene {
WindowGroup {
RootView(content: {
ContentView()
})
}
}
}
UIApplication+StatusBarStyle.swift
extension UIApplication {
static var hostingController: HostingController<AnyView>? = nil
static var statusBarStyleHierarchy: [UIStatusBarStyle] = []
static var statusBarStyle: UIStatusBarStyle = .darkContent
func setHostingController(rootView: AnyView) {
let hostingController = HostingController(rootView: AnyView(rootView))
windows.first?.rootViewController = hostingController
UIApplication.hostingController = hostingController
}
static func setStatusBarStyle(_ style: UIStatusBarStyle) {
statusBarStyle = style
hostingController?.setNeedsStatusBarAppearanceUpdate()
}
}
class HostingController<Content: View>: UIHostingController<Content> {
override var preferredStatusBarStyle: UIStatusBarStyle {
return UIApplication.statusBarStyle
}
}
struct RootView<Content: View> : View {
var content: Content
init(@ViewBuilder content: () -> (Content)) {
self.content = content()
}
var body:some View {
EmptyView()
.onAppear {
UIApplication.shared.setHostingController(rootView: AnyView(content))
}
}
}
ContentView.swift
import SwiftUI
struct ContentView: View {
@State var tabRoute = TabRoute.green
enum TabRoute: String, Identifiable {
var id: String {
self.rawValue
}
case green, black, blue, purple
static var all: [TabRoute] {
[.green, .black, .blue, .purple]
}
var bgColor: Color {
switch self {
case .green:
return .green
case .black:
return .black
case .blue:
return .blue
case .purple:
return .purple
}
}
var statusBarStyle: UIStatusBarStyle {
switch self {
case .black:
return .lightContent
default:
return .darkContent
}
}
}
var body: some View {
TabView(selection: $tabRoute) {
ForEach(TabRoute.all) { route in
NavigationView {
ViewExample(isPresented: false, title: route.rawValue, bgColor: route.bgColor, statusBarStyle: route.statusBarStyle)
.navigationTitle(route.rawValue)
.navigationBarTitleDisplayMode(.inline)
}
.navigationViewStyle(StackNavigationViewStyle())
.tabItem {
Text(route.rawValue)
}
.tag(TabRoute(rawValue: route.rawValue))
}
}
.edgesIgnoringSafeArea(.all)
}
}
struct ViewExample: View {
@Environment(\.presentationMode) var presentationMode
@State private var sheetIsPresented = false
@State var isPresented: Bool
var title: String
var bgColor: Color
@State var statusBarStyle: UIStatusBarStyle
var body: some View {
ZStack {
bgColor
}
.onAppear {
UIApplication.statusBarStyleHierarchy.append(statusBarStyle)
UIApplication.setStatusBarStyle(statusBarStyle)
}
.onDisappear {
guard UIApplication.statusBarStyleHierarchy.count > 1 else { return }
let style = UIApplication.statusBarStyleHierarchy[UIApplication.statusBarStyleHierarchy.count - 1]
UIApplication.statusBarStyleHierarchy.removeLast()
UIApplication.setStatusBarStyle(style)
}
.edgesIgnoringSafeArea(.all)
}
}