Reputation: 155
I am trying to apply different styles on parameters or different parts of localised strings. Let me give you two examples:
I have component with text saying 100 users already is already playing where I would like to 100 to be bold and different font size while this whole string should be localised. Therefore number 100 is parameter of localised string.
I have another component which contains text If you choose to continue, you agree to our privacy policy and to our terms and conditions, where both privacy policy and terms and conditions are suppose to be bold and underlined while whole text will be again localised.
Is there a nice way how to achieve this using SwiftUI to make it work on iOS 14+?
Upvotes: 1
Views: 1633
Reputation: 43
I came across a really good article that will help with this by John Sundell. Let me give some example (from the article).
Note: This answer is assuming you already have created a function to use localised strings called Localized. i.e. you will be using something like this to call the localised string "dummy_text".Localized
You can do what was suggested by LuLuGaGa. That is the correct way to bold some text in localised strings. However, this will not allow you to use custom fonts size or even font weight (as you mentioned in the thread). You can use the approach by John Sundell in the linked article. This involves creating a private extension which will implement a generic, reduce-style rendering function that takes an initial result, as well as a handler that performs the actual string concatenation e.g.
private extension Localized {
func render<T>( into initialResult: T, handler: (inout T, String, _ isBold: Bool) -> Void ) -> T {
let components = localized.components(separatedBy: "**")
let sequence = components.enumerated()
return sequence.reduce(into: initialResult) { result, pair in
let isBold = !pair.offset.isMultiple(of: 2)
handler(&result, pair.element, isBold)
}
}
}
Secondly, you can create an extension to SwiftUI Text()
. Which utilises SwiftUI's ability to directly concatenate raw String values using the +
operator. It allows you to use your own custom fonts Like this:
extension Localized {
func styledLocalizedString(size: CGFloat, weight: some_font_weight) -> Text {
render(into: Text("")) { fullText, string, isBold in
var text = Text(string)
if isBold {
text = text.font(some_bold_font)
} else {
text = text.font(weight)
}
fullText = fullText + text
}
}
}
Then we can use this new function to create an extension to Text()
and utilise the localised styling functionality.
extension Text {
init(localizedString string: String, size: CGFloat, weight: some_font_weight) {
self = string.styledLocalizedString(size: size, weight: weight)
}
}
We can use the above in code like this:
Text(localizedString: "NewMovies", size: 13, weight: "Charter Bold" )
Upvotes: 0
Reputation: 14418
You can include markdown in your localised strings like this:
"%lld users playing" = "**%lld** users already are already playing";
"legal disclaimer" = "If you choose to continue, you agree to our *Privacy Policy* and *Terms and Conditions*";
and then all you can use them directly in Text initialiser:
Text("\(100) users playing")
Text("legal disclaimer")
which looks like this:
Upvotes: 1