Calculating Text Height as per Apple Documentation

92 Views Asked by At

I followed this to try and determine the height of a container I would need before placing text in a CATextLayer. However, I am not getting the expected results. The returned NSRect is (0.0, 0.0, 0.0, 0.0). What am I doing wrong?

func heightForStringDrawing(myString: NSString, myFont: NSFont, myWidth: CGFloat) -> NSRect {
    
    let textStorage:NSTextStorage = NSTextStorage.init(string: myString as String)
    let textContainer:NSTextContainer = NSTextContainer.init(containerSize: NSMakeSize(myWidth, CGFloat.infinity))
    let layoutManager:NSLayoutManager = NSLayoutManager()
    layoutManager.addTextContainer(textContainer)
    layoutManager.glyphRange(for: textContainer)
    textStorage.addLayoutManager(layoutManager)
    textStorage.addAttributes([NSAttributedString.Key.font : myFont], range: NSMakeRange(0, textStorage.length))
    textContainer.lineFragmentPadding = 0.0

    return layoutManager.usedRect(for: textContainer)
}

And I am calling it like this:

print(myLayers.heightForStringDrawing(myString: "Some really, really, really, very long text.", myFont: NSFont.systemFont(ofSize: 14), myWidth: 66))

This results in a returned NSRect as (0.0, 0.0, 0.0, 0.0), but I expect (0.0, 0.0, 66.0, (a number larger than 0.0 or 14.0)). It's not even returning the width.

If I send an empty myString = "" I get a returned NSRect of (0.0, 0.0, 0.0, 14.0). But still no width, as supplied in the call.

1

There are 1 best solutions below

1
matt On BEST ANSWER

So it appears that you simply didn't translate the code they gave you into Swift correctly. Translate the code they give you in the order they give it to you, like this:

func heightForStringDrawing(myString:String, myFont:NSFont, myWidth: GFloat) -> NSRect {
    let textStorage = NSTextStorage(string: myString)
    let textContainer = NSTextContainer(containerSize: NSMakeSize(myWidth, .greatestFiniteMagnitude))
    let layoutManager = NSLayoutManager()
    layoutManager.addTextContainer(textContainer)
    textStorage.addLayoutManager(layoutManager)
    textStorage.addAttributes([.font : myFont], range: NSMakeRange(0, textStorage.length))
    textContainer.lineFragmentPadding = 0.0
    layoutManager.glyphRange(for: textContainer) // <- here
    return layoutManager.usedRect(for: textContainer)
}