I have a Picker in my Settings tab that displays all the supported languages to the user. Showing the language codes is not very human-readable, so I display the localizedString
s in the Picker instead. I need to retrieve the original language code back from this localizedString
, however, to store it in the UserDefault
(or in this case, through the @AppStorage
). Is there a way to do this through Locale
(or any other built-in library)? I read the documentation and tried looking for similar questions on StackOverflow / the Apple developer forum, but all questions seem to be about language code --> localizedString
, rather than localizedString
-> language code. Alternatively, I can also make an enum that stores all this information for me, but I'd like to know whether there's a better way of doing this.
The code:
@AppStorage("language") var language: String = "en"
@State var selectedLanguage = "English"
Picker("settingsTabGeneralSectionHeader".localized(), selection: $selectedLanguage) {
ForEach(Bundle.main.localizations, id: \.self) {
Text((Locale.current as NSLocale).localizedString(forLanguageCode: $0)!)
}
}
.onChange(of: selectedLanguage) { selection in
language = ??? // Inverse of Locale.localizedString
}
Thank you.
CodePudding user response:
We can bind Picker
selection directly to AppStorage
and use code as tag to match, so code is simplified to
struct ContentView: View {
@AppStorage("language") var language: String = "en"
var body: some View {
VStack {
Text("Selected: " language)
Picker("", selection: $language) {
ForEach(Bundle.main.localizations, id: \.self) {
Text((Locale.current as NSLocale)
.localizedString(forLanguageCode: $0)!).tag($0) // << here !!
}
}
}
}
}
and selection separated from presentation.
Tested with Xcode 13.4 / iOS 15.5