0

I want to apply a specific font to an NSMutableAttributedString where no .font attribute is applied. How could I achieve that? I tried enumerating the attributes that contain a font and extracting the ranges but I am kind of lost to the complexity of finding the ranges that don't contain a font attribute since I think I must handle intersections or possible unknown scenarios. Is there a simple way to do it? What I did until now:

        var allRangesWithFont = [NSRange]()
        let stringRange = NSRange(location: 0, length: length)
        
        beginEditing()
        enumerateAttribute(.font,
                           in: stringRange,
                           options: .longestEffectiveRangeNotRequired) { (value, range, stop) in
            
            if let f = value as? UIFont {
                allRangesWithFont.append(range)
            }
        }

1 Answer 1

2

Change your way of thinking, instead, check if the font is not there, and apply your new font directly.

With attrStr being your NSMutableAttributedString, and newFont the font you want to apply.

let newFont = UIFont.italicSystemFont(ofSize: 15)
attrStr.enumerateAttribute(.font, in: NSRange(location: 0, length: attrStr.length), options: []) { value, subrange, pointeeStop in
    guard value == nil else { return }
    attrStr.addAttribute(.font, value: newFont, range: subrange)
}
Sign up to request clarification or add additional context in comments.

2 Comments

That was so obvious, I went on the presumption that enumerateAttribute only returned ranges where the font was found, thanks! The if let f = value as? UIFont check was for CTFont and other possible font classes but I did not expect it to return the range if no font was set and I did not even check, my bad.
You are enumerating on NSAttributedStringKey.font, so value will be a UIFont?. If you enumerate all attributes, then, indeed you need to check as? UIFont.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.