#swift #swiftui
#swift #swiftui
Вопрос:
Я пытаюсь сохранить значение enum в UserDefaults. Для этого я создал пользовательскую привязку. Часть UserDefault работает нормально, но, к сожалению, значение в NavigationView не обновляется после изменения значения с помощью средства выбора.
Как я могу отобразить выбранное погодное условие?
PS: Если это не создает дополнительных сложностей, я бы хотел сохранить погоду перечисления типа Int.
import SwiftUI
enum Weather: Int, CaseIterable {
case rain
case sun
case clouds
}
func getWeatherText(weather: Weather) -> String {
switch weather {
case .rain: return "Rain"
case .sun: return "Sun"
case .clouds: return "Clouds"
}
}
struct ContentView: View {
let currentWeather = Binding<Weather>(
get: {
(Weather(rawValue: UserDefaults.standard.integer(forKey: "weather")) ?? .sun)
},
set: {
UserDefaults.standard.set($0.rawValue, forKey: "weather")
}
)
let weathers = Weather.allCases
var body: some View {
NavigationView{
Form{
Picker("Weather", selection: currentWeather) {
ForEach(weathers, id: .self) { w in
Text(getWeatherText(weather: w)).tag(w)
}
}
}
}
}
}
Комментарии:
1. Разве вы не хотите вместо этого использовать AppStorage? Привязка не является динамическим свойством, поэтому она не приводит к принудительному перестроению тела представления. Вам нужно либо состояние, либо ObservedObject.
2. @AppStorage был именно тем, что мне было нужно. Спасибо!
Ответ №1:
Благодаря комментарию Asperi решение простое: заменить мою пользовательскую привязку на @AppStorage. Это результат:
import SwiftUI
enum Weather: Int, CaseIterable {
case rain
case sun
case clouds
}
func getWeatherText(weather: Weather) -> String {
switch weather {
case .rain: return "Rain"
case .sun: return "Sun"
case .clouds: return "Clouds"
}
}
struct ContentView: View {
@AppStorage("weather") var currentWeather: Weather = Weather.clouds
let weathers = Weather.allCases
var body: some View {
NavigationView{
Form{
Picker("Weather", selection: $currentWeather) {
ForEach(weathers, id: .self) { w in
Text(getWeatherText(weather: w)).tag(w)
}
}
}
}
}
}