从UserDefaults中提取一个Picker



我觉得我一定做了什么蠢事。我所要做的就是从UserDefaults中拉出一个Picker值,然后在Picker改变时保存到UserDefaults。当我尝试让代码在iOS14和ios15上工作时,我遇到了这个问题。

struct SettingsView: View {
@State var rangeSelection: Int = UserDefaults.standard.integer(forKey: "vocalRange")
@State var rangeOptions = ["Soprano", "Mezzo-Soprano/Alto", "Extended Range"]


var body: some View {
VStack{
Form {
Section {
Picker(selection: $rangeSelection, label: Text("Range")) {
ForEach(0 ..< rangeOptions.count, id: .self) { range in
Text(rangeOptions[range])
.tag(range)
}
}
.onChange(of: rangeSelection, perform: { value in
UserDefaults.standard.setValue(rangeSelection, forKey: "vocalRange")
})
}
}
}
.navigationTitle("Settings")
.navigationBarTitleDisplayMode(.inline)
}
}

这似乎工作得很好,和'onChange'火很好。唯一奇怪的是,如果你离开页面并立即返回,'rangeSelection'变量重置为它最初的值。然而,一旦你重新启动应用程序,更改就会正确地反映出来。


作为替代方案,我尝试了以下

@State var rangeSelection: Int = 0
...
.onAppear(perform:{
rangeSelection = UserDefaults.standard.integer(forKey: "vocalRange")
})

这产生了另一个有趣的问题。在iOS15中它工作得很好,但在iOS14中,一旦你改变了选择器,OnAppear会在OnChange之前触发,并将选择器恢复到之前的值。这只是因为我在表单/列表中使用选择器,所以当你选择选择器时它会改变页面。

我觉得我应该使用一个明显的解决方案。

感谢@loremipsum,我使用了AppStorage。我像这样声明变量,不需要'onChange' !

@AppStorage("vocalRange") var rangeSelection: Int = UserDefaults.standard.integer(forKey: "vocalRange")

你可以在。onappear方法中设置延迟来工作

.onAppear(perform:{
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
rangeSelection = UserDefaults.standard.integer(forKey: "vocalRange")
}
})

相关内容

  • 没有找到相关文章

最新更新