1

I have a string and I want to change colors of two words in that string. So, I created a function

func setup()
    {

        let main_string = "By continuing you agree to our Term of use and Privacy Policy "

        var string_to_color = ["By continuing you agree to our","and"]

        for i in 0..<2
        {

            let range = (main_string as NSString).range(of: string_to_color[i])

            let attributedString = NSMutableAttributedString.init(string:main_string)

            attributedString.addAttribute(NSAttributedStringKey.foregroundColor, value: UIColor.black , range: range)

            privacyL.attributedText = attributedString

        }

But, it only changes the colour for the second word and not for the first one.

Can anyone help?

Kaushik Makwana
  • 1,329
  • 2
  • 14
  • 24
Rob
  • 2,086
  • 18
  • 25
  • 1
    Alors, you are doing a for loop, but overriding each time `privacyL.attributedText`. Note that `range(of:)` returns only FIRST occurence found, so if `main_string` was `"and and"`, only first one would be colored. – Larme Mar 12 '18 at 09:42
  • Yeah, so what can I do to colour the second and in "and and"? – Rob Mar 12 '18 at 09:46

2 Answers2

2
let main_string = "By continuing you agree to our Term of use and Privacy Policy "

var string_to_color = ["By continuing you agree to our","and"]

for i in 0..<2
{

    let range = (main_string as NSString).range(of: string_to_color[i])

    let attributedString = NSMutableAttributedString.init(string:main_string)

    attributedString.addAttribute(NSAttributedStringKey.foregroundColor, value: UIColor.black , range: range)

    privacyL.attributedText = attributedString

}

You are overriding each time privacyL.attributedText, so you'll get only the "result" of last iteration.

Instead, do:

let attributedString = NSMutableAttributedString.init(string:main_string)
for i in 0..<2
{
    let range = (main_string as NSString).range(of: string_to_color[i])
    attributedString.addAttribute(NSAttributedStringKey.foregroundColor, value: UIColor.black , range: range)

}
privacyL.attributedText = attributedString

Now, next issues: Don't do a loop for i in 0..<2, instead use at least the count of string_to_color (or a for each loop). If tomorrow you add a string in it or remove one, you'll encounter an issue.

Also range(of:) will return the first occurence found, so if you have:

let main_string = "and and"
var string_to_color = ["something", "and"]

only the first "and" will be colored.

You have then to iterate or use a NSRegularExpression. Here is a related question: Color all occurrences of string in swift

Larme
  • 24,190
  • 6
  • 51
  • 81
0

Just want to add to Larme's answer. You can create extension of String, which will be responsible for string coloring

extension String {
    func colored(_ strings: [String], with color: UIColor) -> NSAttributedString {
        let attributedString: NSMutableAttributedString = NSMutableAttributedString(string: self)
        for string in strings {
            let range = (self as NSString).range(of: string)
            attributedString.addAttribute(NSAttributedStringKey.foregroundColor, value: color , range: range)
        }
        return attributedString
    }
}

And now you can use it anywhere in your code, like this:

let main_string = "By continuing you agree to our Term of use and Privacy Policy "
let string_to_color = ["By continuing you agree to our","and"]
privacyL.attributedText = main_string.colored(string_to_color, with: UIColor.red)
Taras Chernyshenko
  • 2,729
  • 14
  • 27