Search code examples
iosswiftnslayoutconstraintnsmutableattributedstring

NSmutablestring with 2 line breaks crash the program


I need to create an Nsmutableattributed String that starts with line break, the code are like below:

let dateString = TimeUtils.formatTimeOnly(from: data.date!)
let dateMutableString = NSMutableAttributedString.init(string: "\n\(dateString)")
let range = NSRange(location: 0, length: (dateString.count + 2))
dateMutableString.addAttributes([NSFontAttributeName: UIFont(name: "SourceSansPro-Regular", size: 11)!, NSForegroundColorAttributeName: UIColor.gray], range: range)

if I only start the string with only one \n it will crashed the program on the addattributes line, but if I use \n\n then it wont break the program. Can I know what's really going on here?


Solution

  • If there is only one extra character then dateString.count + 2 is longer than the string and you get a crash because the range isn't valid.

    Why base the range length on dateString.count + 2? Why not build the string you want, then pass that string to the NSMutableAttributedString initializer? Then you can directly get that string's length. And why not pass the desired attributes to the initializer since you want them applied to the whole string anyway?

    Besides that, you can't use count on a Swift string to get the length when working with NSString or NSAttributedString. You need to use dateString.utf16.count. This is because NSRange for NSString and NSAttributedString is based on 16-bit characters.

    Here is a simpler way to create the attributed string where the attributes are applied to the whole string:

    let dateString = TimeUtils.formatTimeOnly(from: data.date!)
    let dateAttributes = [NSFontAttributeName: UIFont(name: "SourceSansPro-Regular", size: 11)!, NSForegroundColorAttributeName: UIColor.gray]
    let dateMutableString = NSMutableAttributedString(string: "\n\(dateString)", attributes: dateAttributes)