Search code examples
swiftattributesnsattributedstring

Swift. Add attributes to multiple instances


I have arrays containing strings of the text terms to which I want to apply a particular attribute. Here's a code snippit:

static var bold = [String]()
static let boldAttribs = [NSFontAttributeName: UIFont(name: "WorkSans-Medium", size: 19)!]
for term in bold {
    atStr.addAttributes(boldAttribs, range: string.rangeOfString(term))
}

This works great for single term or phrase use. But it only applies to the first use of a specific term. Is there a way, without resorting to numerical ranges, to apply the attribute to all instances of the same term? For example, make every use of "animation button" within the same string bold.

Edit: This works.

// `butt2` is [String]() of substrings to attribute
// `term` is String element in array, target of attributes
// `string` is complete NAString from data
// `atStr` is final
for term in butt2 {
    var pos = NSRange(location: 0, length: string.length)
    while true {
        let next = string.rangeOfString(term, options: .LiteralSearch, range: pos)
        if next.location == NSNotFound {    break   }

        pos = NSRange(location: next.location+next.length, length: string.length-next.location-next.length)

        atStr.addAttributes(butt2Attribs, range: next)
    }
}

Solution

  • You don't have to resort to numerical ranges, but you do need to resort to a loop:

    // atStr is mutable attributed string
    // str is the input string
    atStr.beginEditing()
    var pos = NSRange(location: 0, length: atStr.length)
    while true {
        let next = atStr.rangeOfString(target, options: .LiteralSearch, range: pos)
        if next.location == NSNotFound {
            break
        }
        atStr.addAttributes(boldAttribs, range: next)
        print(next)
        pos = NSRange(location: next.location+next.length, length: atStr.length-next.location-next.length)
    }
    atStr.endEditing()