Antoine Antoine - 3 months ago 5x
iOS Question

Changing font of strings separated by spaces

I'm trying to make the words split by spaces green in a UITextField, kind of like the way it works when you compose of a new iMessage. I commented out the part of my code that's giving me a runtime error. Please let me know if you have any ideas:

func textChanged(sender : UITextField) {

var myMutableString = NSMutableAttributedString()

let arr = sender.text!.componentsSeparatedByString(" ")

var c = 0

for i in arr {


myMutableString.addAttribute(NSForegroundColorAttributeName, value: UIColor.greenColor(), range: NSRange(location:c,length:i.characters.count))

sender.attributedText = myMutableString



c += i.characters.count + 1




Your code has at least two parts needed to be fixed.

var myMutableString = NSMutableAttributedString()

This line creates an empty NSMutableAttributedString. Any access to the content may cause runtime error.

The other is i.characters.count. You should not use Character based locations and counts, when the APIs you want use is based on the behaviour of NSString. Use UTF-16 based count.

And one more, this is not critical, but you should use sort of meaningful names for variables.

So, all included:

func textChanged(sender: UITextField) {
    let text = sender.text ?? ""
    let myMutableString = NSMutableAttributedString(string: text)
    let components = text.componentsSeparatedByString(" ")
    var currentPosition = 0
    for component in components {
        myMutableString.addAttribute(NSForegroundColorAttributeName, value: UIColor.greenColor(), range: NSRange(location: currentPosition,length: component.utf16.count))
        sender.attributedText = myMutableString

        print(currentPosition, component.utf16.count)
        currentPosition += component.utf16.count + 1

But whether this works as you expect or not depends on when this method is called.