I need to draw an attributed string into a given rectangle. The string's height should be the same as the rectangle's height. This should work with any font a user chooses. To make it a bit more complicated, the string should also fill the rect if it consists only of uppercase characters or only of lowercase characters.
I am using NSLayoutManager to find the "best" font size for the selected font and the given recht and it works quite good with some fonts but with others it doesn't. Seems like the computed font size is always a bit too small and for some fonts it seems like the baseline must be corrected. Unfortunately I didn't find a way to calculate a baseline offset that really works with any font. I attached some sample images showing the issue.
Just posting this to make sure I am not running in the complete wrong direction. Any help would be highly appreciated. Thanks!
but if I try to create a NSTextLineFragment from an attributed string,typographicBounds always returns {{0, 0}, {0, 0}}…
Yeah, that's because the text isn't laid out yet. To lay out the text, you need to set up the TextKit2 stack. The following code retrieves the size of an attributed string (NSAttributedString
):
func sizeOf(nsAttributedString: NSAttributedString, width: CGFloat) -> CGSize {
let textContainer = NSTextContainer(size: CGSize(width: width, height: 0))
textContainer.lineFragmentPadding = 0
let textLayoutManager = NSTextLayoutManager()
textLayoutManager.textContainer = textContainer
let textContentStorage = NSTextContentStorage()
textContentStorage.attributedString = nsAttributedString
textContentStorage.addTextLayoutManager(textLayoutManager)
textLayoutManager.ensureLayout(for: textLayoutManager.documentRange)
let rect = textLayoutManager.usageBoundsForTextContainer
return rect.size
}
Best,
——
Ziqiao Chen
Worldwide Developer Relations.