当我的基于 SwiftUI 的应用程序以横向模式启动时,导航栏上的背景颜色未设置

Background color on Navigation Bar is not set when my SwiftUI based app is launched in landscape mode

我正在使用基于 SwiftUI 的应用程序,该应用程序依赖于 NavigationView 从屏幕转换。

我需要在导航栏上设置背景颜色,并且找到了大多数情况下都能正常工作的代码。

当应用程序以纵向模式启动时,旋转时一切正常。

但是,当应用程序以横向模式启动时,该栏默认为灰色,并且仅在第一次旋转后更新。

下面,我有最少的代码来重现我的问题:

import SwiftUI

struct ContentView: View {
    var body: some View {
        return NavigationView {
            List {
                NavigationLink(destination: Text("A")) {
                    Text("See A")
                }
            }
            .background(NavigationConfigurator { navigationConfigurator in
                navigationConfigurator.navigationBar.barTintColor = .orange
            })
            .navigationBarTitle(Text(verbatim: "Home"), displayMode: .inline)
        }
        .navigationViewStyle(StackNavigationViewStyle())
    }
}

struct NavigationConfigurator: UIViewControllerRepresentable {
    var configure: (UINavigationController) -> Void = { _ in }

    func makeUIViewController(context: UIViewControllerRepresentableContext<NavigationConfigurator>) -> UIViewController {
        UIViewController()
    }

    func updateUIViewController(_ uiViewController: UIViewController,
                                context: UIViewControllerRepresentableContext<NavigationConfigurator>) {
        if let navigationController = uiViewController.navigationController {
            self.configure(navigationController)
            print("Successfully obtained navigation controller")
        } else {
            print("Failed to obtain navigation controller")
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

应用程序在纵向模式下启动时的显示方式:

...并旋转为横向...

最后,在横向模式下启动时的外观。

我也注销了 NavigationConfigurator 并发现当它以纵向模式启动时,会进行两次调用。第一个找不到导航控制器,但是第二个找到了。

当我在横向模式下启动时,只进行了一次调用但找不到它。旋转后,它会找到它并成功更新颜色。

我曾尝试通过 @State 管理强制重绘,但没有成功。

除了将应用程序锁定为纵向模式,我 运行 没有想法。

如果只是关于条形图的颜色,而不需要更多的导航控制器,那么使用外观更简单,因为

struct ContentView: View {
    init() {
        UINavigationBar.appearance().barTintColor = UIColor.orange
    }
    // .. your other code here

此解决方案适用于任何初始方向。使用 Xcode 11.4.

测试

备用:

如果您仍然想通过配置器访问,根据我的经验,以下解决方案(经过测试和工作)更可靠

struct NavigationConfigurator: UIViewControllerRepresentable {
    var configure: (UINavigationController) -> Void = { _ in }

    func makeUIViewController(context: UIViewControllerRepresentableContext<NavigationConfigurator>) -> UIViewController {
        let controller = UIViewController()
        DispatchQueue.main.async {
            if let navigationController = controller.navigationController {
                self.configure(navigationController)
                print("Successfully obtained navigation controller")
            } else {
                print("Failed to obtain navigation controller")
            }
        }
        return controller
    }

    func updateUIViewController(_ uiViewController: UIViewController,
                                context: UIViewControllerRepresentableContext<NavigationConfigurator>) {
    }
}