SwiftUI Text and LocalizedStringKey with parameter
Use this extension
extension String {
public func localized(with arguments: [CVarArg]) -> String {
return String(format: NSLocalizedString(self, comment: ""), locale: nil, arguments: arguments)
}
}
Usage :
Text(LocalizationWrapper.helloWorldWithParameter.localized(with: [name]))
Also, This approach is correct
static func helloWithParameter(parameter: String) -> LocalizedStringKey {
return "helloWorld \(parameter)"
}
SwiftUI Localization and Enums
The answer is much simpler than writing extensions and doing complicated work. Instead of writing a static let, when a variable is present you write a static func. This all takes place in the LocalizationString.swift file's enum and looks like this:
static func testText(name: String) -> LocalizedStringKey { LocalizedStringKey("TEST_TEXT \(name)") }
To use this in your view:
Text(LocalizationStrings.testTest(name: varname))
If you need more variables, just add them into the function.
How to get string value from LocalizedStringKey?
I think it's because SwiftUI is not mean't to do localization from code behind, all localization must happen in view declaration.
However there's a way to achieve that via extensions methods :
extension LocalizedStringKey {
/**
Return localized value of thisLocalizedStringKey
*/
public func toString() -> String {
//use reflection
let mirror = Mirror(reflecting: self)
//try to find 'key' attribute value
let attributeLabelAndValue = mirror.children.first { (arg0) -> Bool in
let (label, _) = arg0
if(label == "key"){
return true;
}
return false;
}
if(attributeLabelAndValue != nil) {
//ask for localization of found key via NSLocalizedString
return String.localizedStringWithFormat(NSLocalizedString(attributeLabelAndValue!.value as! String, comment: ""));
}
else {
return "Swift LocalizedStringKey signature must have changed. @see Apple documentation."
}
}
}
Sadly you must use Reflection
to achieve that as key
has an internal
level of protection in LocalizedStringKey
, use at your own risks.
Use asis :
let s = l10n.helloWorld.toString();
How to use interpolation with strings that rely on automatic grammar agreement?
I was actually very close with this piece of code:
Text("\(String(localized: String.LocalizationValue("Subscription period: \(value) \(unit)"))) free")
But using String(localized:)
isn't correct. I guess it's because automatic grammar agreement uses markdown, which is the prerogative of AttributedString
. We should use AttributedString(localized:)
. But even then, it's not going to inflect because apparently there is a bug in Foundation. But once it gets patched, it will work like a charm.
Here is the correct solution:
func freeTrialDuration() -> Text {
// Use plain string.
let duration: String = "^[\(value) ^[\(unit.lowercased())](grammar: { partOfSpeech: \"noun\" })](inflect: true)"
// Use the following way to get the localized string.
let localizedDuration = AttributedString(localized: String.LocalizationValue(duration))
return Text("\(localizedDuration) free")
}
% symbol in an NSLocalizedString
I think the problem is not with the NSLocalizedString
, but with NSLog
's interpretation of %
symbol. If you pass a format string to NSLog
, and put the string that you would like to show as an object parameter, the percentage sign %
should survive:
NSLog(@"%@", [NSString stringWithFormat:NSLocalizedString(@"KEY", nil),80.1]);
Related Topics
Why am I Allowed Method Access Less Restrictive Than Class Access
How to Integrate Uiactivityviewcontroller with Swiftui's Scrollview
How to Split an Int to Its Individual Digits
Localizewithformat and Variadic Arguments in Swift
How to Create Several Cached Uicolor
How to Use Alamofire with Custom Headers for Post Request
How to Improve Camera Quality in Arkit
Obj-C Cocoapods + Swift Framework
Could Not Find an Overload for '^' That Accepts the Supplied Arguments
For Loop Cycle Showing Always the Last Array Value Swift 3 After Http Request
Block Scroll Down in Scrollview - Swiftui
Cannot Load Underlying Module for Xctest
What Is a 'Non-Nominal Type' in Swift
Swift: How to Assign a Variable by Reference, Not by Value
Using Non Ns_Enum Objective-C Enum in Swift
Firebase Storage Downloadurl()' Is Deprecated: Use 'Storagereference.Downloadurlwithcompletion()