Applying Text Attributes to ALL Occurrence of certain string

时间:2015-07-28 16:57:23

标签: ios string swift

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

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:2)

此处返回字符串出现范围数组的代码。我使用了JustAnotherCoder的代码。然后你可以遍历范围。我只是将代码概括为其他用途。

  

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
}

答案 2 :(得分:1)

使用字符串扩展更新了@Khaled Annajar对 Swift 4 的回答:

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
}

}