I am using the following extension to change "NSMutableAttributedString" colour and it did the trick nicely. It can be used as a template
extension NSMutableAttributedString {
func changeColourOf(_ terms: [String], toThisColour termsColour: UIColor,
andForegroundColour fontColour: UIColor) {
// Set your foreground Here
addAttributes([NSAttributedString.Key.foregroundColor : fontColour],
range: NSMakeRange(0, self.length))
// Convert "NSMutableAttributedString" to a NSString
let string = self.string as NSString
// Create a for loop for ther terms array
for term in terms {
// This will be the range of each term
let underlineRange = string.range(of: term)
// Finally change the term colour
addAttribute(NSAttributedString.Key.foregroundColor,
value: termsColour,
range: underlineRange)
}
}
}
Example:
let someMutableStr = NSMutableAttributedString(string: "Hello World 2017 !")
someMutableStr.changeColourOf(["Hello", "2017"],
toThisColour: .blue,
theStringFontColour: .red)
Edit 2021
extension NSMutableAttributedString
{
func colourTerms(_ terms:[String] = [],
withColour colour:UIColor = .blue,
onforegroundColour foregroundColour:UIColor = .white)
{
let fontSize:CGFloat = 25
self.addAttributes([NSAttributedString.Key.font:UIFont.systemFont(ofSize: fontSize),NSAttributedString.Key.foregroundColor:foregroundColour], range:NSMakeRange(0, self.length) )
let text = self.string
for term in terms
{
let charCount = term.count
var options:NSString.EnumerationOptions = .byWords
switch charCount
{
case 1:
options = .byComposedCharacterSequences
default:
if term.contains(" ")
{
options = .bySentences
}else
{
options = .byWords
}
}
string.enumerateSubstrings(in: text.startIndex..<text.endIndex,
options: options)
{ (subString,substringRange,_,_) in
if subString!.contains(term)
{
self.addAttribute(NSAttributedString.Key.foregroundColor,
value: colour,
range: NSRange(substringRange, in: text))}}}}}
Example 2021
let attrText = NSMutableAttributedString(string: """
Hello World 2021!
Happy 2021
""")
attrText.colourTerms(["Hello","2021"])
//Before this second color will stay the same , now fixed!
//See images below
Example 2017
Here is the problem
Now