SwiftUI - динамически обновлять sh UINavigationBar.appearance (). BackgroundColor - PullRequest
0 голосов
/ 17 июня 2020

Я пытаюсь реализовать селектор цветовой темы в своем приложении. Последнее препятствие, которое я пытаюсь преодолеть, - это динамическое изменение цвета моей UINavigationBar. В настоящее время моя функция по изменению цвета работает, но она вступает в силу только тогда, когда приложение было перезапущено из закрытого состояния.

Мой root контроллер представления устанавливает начальное состояние UINavigationBar следующим образом:

struct MyRootView: View {

            init() {
                UINavigationBar.appearance().backgroundColor = getPreferredThemeColour() 
                UINavigationBar.appearance().largeTitleTextAttributes = [
                    .foregroundColor: UIColor.white]
            }

var body: some View {
...

getPreferredThemeColour () просто возвращает желаемый UIColour из UserDefaults

В моем селекторе темы есть кнопки, которые изменяют атрибуты цвета следующим образом:

 Button(action: {
 UserDefaults.standard.set(UIColor.blue, forKey: "theme")
 UINavigationBar.appearance().backgroundColor = UIColor.blue }) {

Я не могу кажется, нашел способ обновить sh UINavigationBar «на лету», чтобы отразить сделанные изменения. Приложение всегда необходимо перезапускать.

Любая помощь будет очень признательна !!!! Спасибо.

1 Ответ

0 голосов
/ 17 июня 2020

Внешний вид применяется к экземплярам, ​​созданным после самого внешнего вида . Таким образом, решение состоит в том, чтобы воссоздать NavigationView после изменения внешнего вида.

Вот отработанная демонстрация подхода. Протестировано с Xcode 11.4 / iOS 13.4

demo

struct DemoNavigationBarColor: View {
    @State private var force = UUID()

    init() {
        let navBarAppearance = UINavigationBarAppearance()
        navBarAppearance.configureWithOpaqueBackground()
        navBarAppearance.backgroundColor = UIColor.systemRed

        UINavigationBar.appearance().standardAppearance = navBarAppearance
    }

    var body: some View {
        VStack {
            NavigationView(){
                List(1 ... 20, id: \.self) { item in
                    NavigationLink(destination:
                        Text("Details \(item)")
                    ) {
                        Text("Row \(item)")
                    }
                }
                .navigationBarTitle("Title", displayMode: .inline)

            }.id(force)  // recreate NavigationView

            Button("Be Green") {
                UINavigationBar.appearance().standardAppearance.backgroundColor = UIColor.systemGreen
                self.force = UUID() // << here !!
            }
        }
    }
}
...