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 the LocalizedStringResource, which will be the system locale.
Rather than static lets in Constants, you should make the interpolated strings functions, so that you can format them in place:
static func items(_ n: Int) -> LocalizedStringResource {
LocalizedStringResource("\(n) Items", table: "General")
}
Usage:
Text(Constants.items(13))
This work because you are directly giving the resource to Text, and Text can localise it using SwiftUI's environment.
I'm not sure why you are using LocalizedStringResource instead of LocalizedStringKey. Unless you do need specific functionalities from LocalizedStringResource, use LocalizedStringKey instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With