I wish to make an app that helps each English and Japanese, and I have to show a sentence the place a selected phrase (e.g., “Apple”) with a gradient coloration.
Listed below are the necessities:
I wish to show the sentence in each English (e.g., “I like Apple merchandise!”) and Japanese (e.g., “Apple製品が好きです!”).
I wish to apply the gradient solely to the phrase “Apple”.
I do not wish to cut up the sentence into separate string assets for the non-gradient elements (e.g., “I like”, “Apple”, and “merchandise!”) as a result of the sentence construction differs between English and Japanese.
In Japanese, “Apple” comes first, so the view construction could be inconsistent if I break it into a number of Textual content views (3 in English vs. 2 in Japanese).
I wish to move all the sentence as a single string and specify which phrase ought to have the gradient utilized.
I am type of caught now, so when you’ve got an thought, I might love to listen to.
What I attempted
Clear Chosen Textual content Method
I created a technique that makes the chosen textual content clear and overlays the gradient on high of all the sentence:
// This technique makes the chosen textual content clear
func createAttributedString(textToClear: String, wholeText: String) -> AttributedString {
var attrStr = AttributedString(wholeText)
if let vary = attrStr.vary(of: textToClear) {
attrStr[range].foregroundColor = .clear
}
return attrStr
}
Then, I attempted overlaying the “Apple” textual content with a gradient and used the offset modifier to place it:
struct MySampleText: View {
let titleEn = "I like Apple merchandise!"
let titleJp = "Apple製品が好きです!"
var physique: some View {
let title = isEnglish ? titleEn : titleJp
Textual content(createAttributedString(textToClear: "Apple", wholeText: title))
.overlay {
Textual content("Apple")
.overlay {
LinearGradient(
colours: [.red, .blue, .green, .yellow],
startPoint: .main,
endPoint: .trailing
)
}
.masks {
Textual content("Apple")
}
.offset(x: -60, y: 20) // Manually calculating the offset
}
}
}
Challenge: Manually calculating the offset values for “Apple” is tough and error-prone. It turns into difficult to get the place proper for various display sizes and textual content lengths.
Query: Is there a solution to calculate the precise offset of the overlay textual content programmatically?
Gradient Over Complete Textual content with Masks
I additionally tried making use of a gradient over all the sentence after which masking out the half the place “Apple” ought to be displayed with the gradient:
struct MySampleText: View {
let titleEn = "I like Apple merchandise!"
let titleJp = "Apple製品が好きです!"
var physique: some View {
let title = isEnglish ? titleEn : titleJp
Textual content(title)
.overlay {
// the gradient is utilized to a complete sentence, not the vary of "Apple"
LinearGradient(
colours: [.red, .blue, .green, .yellow],
startPoint: .main,
endPoint: .trailing
)
Textual content(createAttributedString(textToClear: "Apple", wholeText: title))
}
.masks {
Textual content(title)
}
}
}
Challenge: The gradient is utilized to all the sentence, not simply to the phrase “Apple”.
Query: How can I limit the gradient to use solely to the “Apple” a part of the sentence, with out affecting the remainder of the textual content?