从 UserDefaults 中提取 Picker

Posted

技术标签:

【中文标题】从 UserDefaults 中提取 Picker【英文标题】:Pulling from UserDefaults for a Picker 【发布时间】:2021-10-06 05:38:17 【问题描述】:

我觉得我一定是在做一些愚蠢的事情。如果从 UserDefaults 中拉出以设置 Picker 值,然后在 Picker 更改时保存到 UserDefaults,我要做的所有事情。当我尝试使代码适用于 ios14 和 15 时,我遇到了问题。

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 之前触发,并将选择器恢复为之前的值。这只是因为我在表单/列表中使用选择器,所以当您选择选择器时它会更改页面。

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

【问题讨论】:

这是否回答了您的问题***.com/a/66730876/12299030? 我不这么认为:(我的问题似乎源于使用列表选择器样式,而不是上面问题中的 SegmentedPicker。我使用的是这张图片中的第一种,它这就是为什么当用户更改选择器中的值时,OnAppear 会再次触发。“miro.medium.com/max/1400/1*ksvO_QqOxxe3T-AIXU5iYQ.png” 什么是List picker style?我在您的代码中没有看到 .pickerStyle(...)。您是否向我们展示了您不使用的代码? 以这样的方式使用 AppStorage,它也会保存 @loremipsum 啊哈!!不知何故,我不知道 AppStorage 的存在。实施并完美运行,谢谢! 【参考方案1】:

您可以在 .OnAppear 方法中设置延迟来工作

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

【讨论】:

【参考方案2】:

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

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

【讨论】:

以上是关于从 UserDefaults 中提取 Picker的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 UserDefaults swift 3 提取 JobSeekerID

在swift中从数组中提取值

如何从 JDatePicker 中提取和重置日期?

如何从 UserDefaults 向数组添加值?

UserDefaults with Struct - TableView 不显示从 UserDefaults 保存的数据?

从 Swift 中的“UserDefaults”更新值的问题