So this is a weird one...before SwiftUI 2 launched, I set the UINavigationBar.appearance() in the init() of the view as follows:
init(selectedStyle: Binding<Int>) {
_selectedStyle = selectedStyle
if self.selectedStyle == 1 {
UINavigationBar.appearance().backgroundColor = UIColor.init(displayP3Red: 7/255, green: 7/255, blue: 7/255, alpha: 1)
UISegmentedControl.appearance().backgroundColor = .black
UINavigationBar.appearance().titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
UISegmentedControl.appearance().setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.black], for: UIControl.State.selected)
UISegmentedControl.appearance().selectedSegmentTintColor = .white
UISegmentedControl.appearance().setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.white], for: UIControl.State.normal)
} else {
UINavigationBar.appearance().backgroundColor = .white
UISegmentedControl.appearance().backgroundColor = .white
UISegmentedControl.appearance().selectedSegmentTintColor = .white
UINavigationBar.appearance().titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.black]
UISegmentedControl.appearance().setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.black], for: UIControl.State.selected)
UISegmentedControl.appearance().setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.black], for: UIControl.State.normal)
}
}
In SwiftUI 1, the view would initialize again so the new look for the navbar would update correctly. because the init() function would run again. I tried to put the same code inside of an onChange() that's attached to the Picker but for some reason it doesn't work:
Picker(selection: $selectedStyle, label: Text("")) {
ForEach(0 ..< 3) {
Text([$0])
}
}
.pickerStyle(SegmentedPickerStyle())
.onChange(of: selectedStyle, perform: { change in
if self.selectedStyle == 1 {
UINavigationBar.appearance().backgroundColor = UIColor.init(displayP3Red: 7/255, green: 7/255, blue: 7/255, alpha: 1)
UISegmentedControl.appearance().backgroundColor = .black
UINavigationBar.appearance().titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
UISegmentedControl.appearance().setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.black], for: UIControl.State.selected)
UISegmentedControl.appearance().selectedSegmentTintColor = .white
UISegmentedControl.appearance().setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.white], for: UIControl.State.normal)
} else {
UINavigationBar.appearance().backgroundColor = .white
UISegmentedControl.appearance().backgroundColor = .white
UISegmentedControl.appearance().selectedSegmentTintColor = .white
UINavigationBar.appearance().titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.black]
UISegmentedControl.appearance().setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.black], for: UIControl.State.selected)
UISegmentedControl.appearance().setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.black], for: UIControl.State.normal)
}
})
The appearance
have effect on UI elements creates after corresponding appearance is set. So you need to recreate all dependent UI.
The possible approach can be as follows - assuming you have NavigationView
in root of ContentView
, you can recreate it (and so all subviews), by
var body: some View {
NavigationView {
// .. content here
}.id(selectedStyle) // << here !!
}