Цвет фона на панели навигации не устанавливается, когда мое приложение на основе SwiftUI запускается в ландшафтном режиме

Я работаю с приложением на основе 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 управления, но это было неудачно.

Если не считать блокировки приложения в портретном режиме, у меня закончились идеи.

1 ответ

Решение

Если речь идет только о цвете оттенка панели и не нужен контроллер навигации для большего, то проще использовать внешний вид, как

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>) {
    }
}
Другие вопросы по тегам