将 Picker 值存储到 UserDefaults

问题描述

我想将用户对当前语言的选择存储到 UserDefaults。用户通过选择器选择他们喜欢的语言。然而,我不知道如何放置代码来更新 UserDefaults。

这是我的代码

enum Language: Int,CaseIterable,Identifiable {
    case en
    case zh_hant
    
    var description: String {
        switch self {
        case.en:
            return "English"
        case.zh_hant:
            return "繁體中文"
        }
    }
    
    var id: Int {
        self.rawValue
    }
}

然后在我的模型类中:

final class ModelData: ObservableObject {
    // this is to be used as the default when the app is first launch.
    // However,if the user choose the language,the default should be retrieve from UserDefaults
    @Published var currentLanguage: Language = Language.en
}

以及选择语言的用户界面:

struct ConfigurationView: View {
    
    @EnvironmentObject var modelData: ModelData
    
    let lang_title = ["Language","語言"]

    var body: some View {
        List {
            vstack {
                HStack {
                    Text(lang_title[modelData.currentLanguage.rawValue]).font(.title2)
                    Spacer()
                }
                Picker("Language",selection: $modelData.currentLanguage) {
                    ForEach(Language.allCases,id: \.id) { language in
                        Text(language.description).tag(language)
                    }
                }
                .pickerStyle(SegmentedPickerStyle())
            }
            .padding()
        }

    }
}

如何从 UserDefaults 加载所选语言并在用户选择时更新?

解决方法

这是一种可能的方式(您可以根据需要选择存储/恢复的值)

    Picker("Language",selection: $modelData.currentLanguage) {
        ForEach(Language.allCases,id: \.id) { language in
            Text(language.description).tag(language)
        }
    }
    .pickerStyle(SegmentedPickerStyle())
    .onChange(of: modelData.currentLanguage) {
        UserDefaults.standard.setValue($0.rawValue,forKey: "language")
    }

和创建(或在 init 中,如果需要一些解码)

final class ModelData: ObservableObject {
    @Published var currentLanguage = Language(rawValue: UserDefaults.standard.value(forKey: "language") as? Int ?? 0)!
}

作为替代,您可以考虑在 AppStorage 视图中使用 ConfigurationView 属性包装器。

,

我会很简单:

import SwiftUI

final class ModelData: ObservableObject {
    // this is to be used as the default when the app is first launch.
    // However,if the user choose the language,the default should be retrieve from UserDefaults

  @AppStorage("currentLanguage") var currentLanguage: Language = Language.en
}