Harry Blue
Harry Blue

Reputation: 4502

Applying NSMutableAttributedString to a range of text

I have some text:

New Content - Published Today | 10 min read

I'd like to apply styles to everything after and including the pipe, so | 10 min read

I have tried the below but it has only styles the pipe itself.

  func makeAttributedText(using baseString: String?) -> NSMutableAttributedString? {
    guard let baseString = baseString else { return nil }
    let attributedString = NSMutableAttributedString(string: baseString, attributes: nil)
    let timeToReadRange = (attributedString.string as NSString).range(of: "|")
    attributedString.setAttributes([NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 18)], range: timeToReadRange)
    return attributedString
  }

Upvotes: 0

Views: 81

Answers (1)

vadian
vadian

Reputation: 285069

Rather than getting the range of a single character get the index of the character and create a range from that index to the end of the string.

func makeAttributedText(using baseString: String?) -> NSMutableAttributedString? {
    guard let baseString = baseString else { return nil }
    let attributedString = NSMutableAttributedString(string: baseString, attributes: nil)
    guard let timeToReadIndex = baseString.firstIndex(of: "|") else { return attributedString }
    let timeToReadRange = NSRange(timeToReadIndex..., in: baseString)
    attributedString.setAttributes([NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 18)], range: timeToReadRange)
    return attributedString
}

Note:

Swift has dedicated methods to convert Range<String.Index> to NSRange. There's no reason for the bridge cast to NSString

Upvotes: 2

Related Questions