Reputation:
I'm a beginner in Swift and I want to make a custom Label on some letters the font to be bigger, and on some others to be smaller.
Like on image:
So, the currency symbol and decimal points should be in a smaller font than other numbers.
The code I tried to implement is:
// Used this function to get the index of decimal point (.) from the string.
func getDecimalIndex(text: String) -> Int {
let myText = text.firstIndex(of: ".")
return myText?.utf16Offset(in: text) ?? 0
}
func setupLabel(text: String) {
guard !text.isEmpty else { return }
let attributedString = NSMutableAttributedString(string: text)
let decimalStart = getDecimalIndex(text: attributedString.string)
attributedString.addAttribute(.font,
value: UIFont.systemFont(ofSize: 22),
range: NSRange(location: decimalStart, length: attributedString.length))
myLabel.attributedText = attributedString
}
setupLabel(text: "$1100.33")
setupLabel(text: "1100.33€")
Whenever I load the app, it crashes on this line:
attributedString.addAttribute(.font,
value: UIFont.systemFont(ofSize: 22),
range: NSRange(location: decimalStart, length: attributedString.length))
And the error in console is:
Terminating app due to uncaught exception 'NSRangeException', reason: 'NSMutableRLEArray objectAtIndex:effectiveRange:: Out of bounds'
What might be wrong?
Thank you in advance for your contribution.
Upvotes: 0
Views: 350
Reputation: 614
Instead of setting NSRange
for attributedString
you can use several string
with several attributedString-attributes
.
func setupLabel(textSmall: String, textLarge : String) {
let attributeSmall = [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 15)]
let attributeLarge = [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 22)]
let attr1 = NSMutableAttributedString(string: textSmall, attributes: attributeSmall)
let attr2 = NSMutableAttributedString(string: textLarge, attributes: attributeLarge)
attr2.append(attr1)
myLabel.attributedText = attr2
}
use this function by splitting your string with .
let yourValue = "$1100.33"
let smallTxt = yourValue.components(separatedBy: ".")[1]
let largeTxt = "\(yourValue.components(separatedBy: ".")[0])."
setupLabel(textSmall: smallTxt, textLarge: largeTxt)
Upvotes: 1