I'm trying to change a locale on a fly, but it doesn't work for interpolated strings:
//this struct is mandatory
struct Constants {
static let download = LocalizedStringResource("Download", table: "General")
static let items = LocalizedStringResource("%lld item", table: "General")
}
struct ContentView: View {
@State private var language: String = "uk"
var body: some View {
ZStack {
Rectangle().foregroundStyle(.white)
VStack {
Text(Constants.download)
Text(String(format: String(localized:Constants.items), 13))
}
.padding()
}
.onTapGesture {
language = (language == "en") ? "uk" : "en"
}
.environment(\.locale, .init(identifier: language))
.id(language) //try to force reload UI..
}
}
Result:
Also, please note, if you change a scheme language parameter:
Then it will load string and interpolation will work for selected language:
But after that, still, changing a locale doesn't update language value with interpolation.
Looks like a SwiftUI internal logic problem? Or is there maybe could be some workaround for this?
My General.xcstrings translated:




This happens because
String(localized:)doesn't care about SwiftUI's environment. It only looks at the locale of theLocalizedStringResource, which will be the system locale.Rather than
static lets inConstants, you should make the interpolated strings functions, so that you can format them in place:Usage:
This work because you are directly giving the resource to
Text, andTextcan localise it using SwiftUI's environment.I'm not sure why you are using
LocalizedStringResourceinstead ofLocalizedStringKey. Unless you do need specific functionalities fromLocalizedStringResource, useLocalizedStringKeyinstead.