Сохранение значения 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 и обновить, если пользователь выбрал?


person user6539552    schedule 21.03.2021    source источник


Ответы (2)


Вот возможный способ (значение для сохранения/восстановления вы можете выбрать по своему усмотрению)

    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.

person Asperi    schedule 21.03.2021

Я бы просто сделал:

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
}
person federicoramos77    schedule 21.03.2021
comment
Пишет Неизвестный атрибут AppStorage. - person user6539552; 21.03.2021
comment
не забудьте импортировать SwiftUI в файл - person federicoramos77; 21.03.2021