SwiftUI: собственный ViewModifier не обновляет представление
В моем проекте у меня есть два палитры цветов, которые меняют цвет фона и цвет шрифта.
Лист, на котором я меняю Цвет:
@ObservedObject var listColor: ListColor
ColorPicker("Hintergrund", selection: $listColor.bgColor)
ColorPicker("Text", selection: $listColor.textColor)
ContentView, где должно отображаться изменение:
@ObservedObject private var listColor = ListColor()
VStack{
VStack{...}
.backgroundColor(listColor.bgColor)
.foregroundColor(listColor.textColor)
}
.navigationBarTitle(Text("Workout"), displayMode: .automatic)
.navigationBarColor(backgroundColor: listColor.bgColorNav, titleColor: listColor.textColorNav) // my own viewmodifier
.navigationBarItems(trailing:
Button(action: {
self.showSettings.toggle()
}) {
Text("Settings")
}
.sheet(isPresented: $showSettings){
SettingsView(listColor: listColor) //open View with the color pickers
})
У меня также есть собственный ViewModifer, который меняет цвет фона и цвет шрифта панели навигации.
struct NavigationBarModifier: ViewModifier {
var backgroundColor: UIColor?
var titleColor: UIColor?
init(backgroundColor: UIColor?, titleColor: UIColor?) {
self.backgroundColor = backgroundColor
let coloredAppearance = UINavigationBarAppearance()
coloredAppearance.configureWithTransparentBackground()
coloredAppearance.backgroundColor = backgroundColor
coloredAppearance.titleTextAttributes = [.foregroundColor: titleColor ?? .white]
coloredAppearance.largeTitleTextAttributes = [.foregroundColor: titleColor ?? .white]
UINavigationBar.appearance().standardAppearance = coloredAppearance
UINavigationBar.appearance().compactAppearance = coloredAppearance
UINavigationBar.appearance().scrollEdgeAppearance = coloredAppearance
}
func body(content: Content) -> some View {
ZStack{
content
VStack {
GeometryReader { geometry in
Color(self.backgroundColor ?? .clear)
.frame(height: geometry.safeAreaInsets.top)
.edgesIgnoringSafeArea(.top)
Spacer()
}
}
}
}
}
Проблема в том, что "нормальный" фон и цвет шрифта меняются, но не в панели навигации. Я думаю, проблема в том, что мой собственный ViewModifier для панели навигации не перезагружает представление. Я сохраняю цвета в UserDefaults; когда я снова запускаю приложение, изменения отображаются на панели навигации.
1 ответ
Вместо использования обычной переменной внутри ViewModifier объявите привязку к
Color
объект. Затем, если ваше обернутое значение изменится, View (который в данном случае NavigationBar) будет автоматически перерисован.
Мой рабочий пример:
import SwiftUI
struct NavigationBarModifier: ViewModifier {
var backgroundColor: Binding<Color>
init(backgroundColor: Binding<Color>) {
self.backgroundColor = backgroundColor
}
func body(content: Content) -> some View {
ZStack{
content
VStack {
GeometryReader { geometry in
self.backgroundColor.wrappedValue
.frame(height: geometry.safeAreaInsets.top)
.edgesIgnoringSafeArea(.top)
Spacer()
}
}
}
}
}
extension View {
func navigationBarColor(_ bgColor: Binding<Color>) -> some View {
self.modifier(NavigationBarModifier(backgroundColor: bgColor))
}
}
struct ContentView: View {
@State private var bgColor = Color(.sRGB, red: 0.98, green: 0.9, blue: 0.2)
var body: some View {
NavigationView {
ColorPicker("NavigationBar background color", selection: $bgColor)
.navigationBarTitle("Title", displayMode: .large)
.navigationBarColor(self.$bgColor)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}