Reputation: 57
I am trying to add color to 2 words in a string. This is the code I am using:
var HighScore:Int = 0
var CurrentScore:Int = 0
let stringOne = "You have managed to score \(CurrentScore). Current record is \(self.HighScore). Play again and give it another try!"
let stringTwo = "\(CurrentScore)"
let stringThree = "\(HighScore)"
let range1 = (stringOne as NSString).range(of: stringTwo)
let range2 = (stringOne as NSString).range(of: stringThree)
let attributedText = NSMutableAttributedString.init(string: stringOne)
attributedText.addAttribute(NSForegroundColorAttributeName, value: UIColor.init(netHex: 0x00b4ff) , range: range1)
attributedText.addAttribute(NSForegroundColorAttributeName, value: UIColor.init(netHex: 0x00b4ff) , range: range2)
gameOverDescriptionLabel.attributedText = attributedText
The problem I have is that if CurrentScore
and HighScore
is the same(ex: 2 & 2) the color on the range2
still stays white, but if they are not equal(2 & 1 or 1 & 2) both gets the color I have choosen.
Any suggestions?
Upvotes: 0
Views: 596
Reputation: 261
//MARK: forgroundColor
open var foregroundColor: UIColor? {
didSet {
textAttributes[NSForegroundColorAttributeName] = foregroundColor
self.attributedText = NSAttributedString(string: self.text, attributes: textAttributes)
}
}
//MARK: backgroundColor
open var textBackgroundColor: UIColor? {
didSet {
textAttributes[NSBackgroundColorAttributeName] = textBackgroundColor
self.attributedText = NSAttributedString(string: self.text, attributes: textAttributes)
}
}
Upvotes: 0
Reputation: 1414
Add this to the top or bottom of your .swift
file:
extension NSMutableAttributedString {
func bold(_ text:String) -> NSMutableAttributedString {
let attrs:[String:AnyObject] = [NSForegroundColorAttributeName: UIColor.init(netHex: 0x00b4ff)]
let boldString = NSMutableAttributedString(string:"\(text)", attributes:attrs)
self.append(boldString)
return self
}
func normal(_ text:String)->NSMutableAttributedString {
let normal = NSAttributedString(string: text)
self.append(normal)
return self
}
}
To code below is the usage, you can edit it how you'd like, but I have made it so you can easy just copy&paste it to your project:
let formattedString = NSMutableAttributedString()
formattedString
.normal("You have managed to score ")
.bold("\(CurrentScore)")
.normal(". Current record is ")
.bold("\(HighScore)")
.normal(". Play again and give it another try!")
gameOverDescriptionLabel.attributedText = formattedString
Upvotes: 1
Reputation: 9392
A solution without searching for the range would be to create 2 separate NSMutableAttributedString for current score and high score, and then append everything together.
let currentScoreString = NSMutableAttributedString(...)
let highscoreString = NSMutableAttributedString(...)
let finalString = NSMutableAttributedString(string: "You have managed to score ").append(currentScoreString)....
Upvotes: 0
Reputation: 535222
If the current score and high score are the same string, searching for the latter finds the former (because the search starts at the beginning).
There are lots of other, better ways to do this.
Perform the second search in a range starting after the result of the first search (range(of:)
has a range:
parameter, but you are not using it)
Instead of looking for the range of the high score, search for the surrounding boilerplate ("You have managed to score" and so on) and figure out where the numbers must be.
Use NSScanner or regular expressions to find the numerical expressions embedded in the string.
My favorite: mark each of the numbers with an "invisible" attribute and search for that attribute so that you can find the numbers reliably (example here).
Upvotes: 1