Using Range<Index> with NSRange in the NSAttributedString API

Jordan H picture Jordan H · Oct 4, 2015 · Viewed 8.1k times · Source

I'm attempting to determine the indexes of occurrences of a given string in a String, then generate an NSRange using those indexes in order to add attributes to an NSMutableAttributedString. The problem is rangeOfString returns Range<Index> but addAttributes:range: expects an NSRange. My attempts to create an NSRange from the start and end indexes of the Range have failed, because String.CharacterView.Index is not an Int, thus it will not compile.

How can one use Range<Index> values to create an NSRange?

var originalString = "Hello {world} and those who inhabit it."

let firstBraceIndex = originalString.rangeOfString("{") //Range<Index>
let firstClosingBraceIndex = originalString.rangeOfString("}")

let range = NSMakeRange(firstBraceIndex.startIndex, firstClosingBraceIndex.endIndex)
//compile time error: cannot convert value of type Index to expected argument type Int

let attributedString = NSMutableAttributedString(string: originalString)
attributedString.addAttributes([NSFontAttributeName: boldFont], range: range)

Answer

matt picture matt · Oct 4, 2015

If you start with your original string cast as a Cocoa NSString:

var originalString = "Hello {world} and those who inhabit it." as NSString

... then your range results will be NSRange and you'll be able to hand them back to Cocoa.