2

Im applying a text attribute the string "Updated - ".

var attributedText: NSMutableAttributedString = NSMutableAttributedString(string: textView.text)
             let rangeOfString = (textView.text as NSString).rangeOfString("Updated - ")
             attributedText.addAttributes([NSFontAttributeName: UIFont.italicSystemFontOfSize(8.0)],range: rangeOfString)
             textView.attributedText = attributedText

I want this to apply to all occurences of the string rather than just the one

Tried

var attributedText: NSMutableAttributedString = NSMutableAttributedString(string: textView.text)
             let stringRange = (textView.text as NSString).rangeOfString("Updated - ")


             if (stringRange.location != NSNotFound) {

                    attributedText.addAttributes([NSFontAttributeName: UIFont.italicSystemFontOfSize(8.0)],range: stringRange)
                    textView.attributedText = attributedText

            }

This still only applies the attributed text to one occurrence of the string

Similar question Color all occurrences of string in swift

Update

var attributedText: NSMutableAttributedString = NSMutableAttributedString(string: textView.text)
             var inputLength = count(attributedText.string)
             let stringRange = "Updated - "

             var searchLength = count(stringRange)
             var range = NSRange(location: 0, length: attributedText.length)

             while (range.location != NSNotFound) {

                range = (attributedText.string as NSString).rangeOfString("Updated - ", options: nil, range: range)

                if (range.location != NSNotFound) {
                     attributedText.addAttribute(NSForegroundColorAttributeName, value: UIFont.italicSystemFontOfSize(8.0), range: NSRange(location: range.location, length: searchLength))
                    range = NSRange(location: range.location + range.length, length: inputLength - (range.location + range.length))
                }
             }

 textView.attributedText = attributedText
Community
  • 1
  • 1
JSA986
  • 5,870
  • 9
  • 45
  • 91

3 Answers3

3

You have to loop through all instances of "Updated - " within your text and grab their range. One way to do this is like so (tailored to your problem from this answer):

var attributedText: NSMutableAttributedString = NSMutableAttributedString(string: textView.text)

while (range.location != NSNotFound) {
    range = (attributedText.string as NSString).rangeOfString("Updated - ", options: nil, range: range)
    if (range.location != NSNotFound) {
         attributedText.addAttributes([NSFontAttributeName: UIFont.italicSystemFontOfSize(8.0)],range: range)
        range = NSRange(location: range.location + range.length, length: inputLength - (range.location + range.length))
    }
}

textView.attributedText = attributedText
Community
  • 1
  • 1
JustAnotherCoder
  • 2,565
  • 17
  • 38
3

Here code that returns an array of ranges of occurrences of the string. I used JustAnotherCoder's code. Then you can loop over the ranges. I just generalized the code for other uses.

Swift 3

func rangesOf(subString: String) -> [NSRange] {
    var ranges = [NSRange]()

    var range: NSRange = NSMakeRange(0, self.characters.count)
    while (range.location != NSNotFound) {
        range = (self as NSString).range(of: subString, options: .caseInsensitive, range: range)
        if (range.location != NSNotFound) {
            ranges.append(range)
            range = NSRange(location: range.location + range.length, length: self.characters.count - (range.location + range.length))
        }
    }
    return ranges
}
Khaled Annajar
  • 15,542
  • 5
  • 34
  • 45
2

Updated @Khaled Annajar's answer for Swift 4 utilizing String Extension:

extension String {

    func ranges(subString: String) -> [NSRange] {
        var ranges = [NSRange]()
        var range = NSRange(location: 0, length: count)
        while range.location != NSNotFound {
            range = (self as NSString).range(of: subString, options: .caseInsensitive, range: range)
            if range.location != NSNotFound {
                ranges.append(range)
                range = NSRange(location: range.location + range.length,
                            length: count - (range.location + range.length))
            }
        }
        return ranges
    }
}
pableiros
  • 14,932
  • 12
  • 99
  • 105
Joshua Hart
  • 772
  • 1
  • 21
  • 31