Following the official docs, I created this function to calculate text height.
func calculateTextHeight(myString: String, myWidth: CGFloat, myFont: UIFont) -> CGFloat {
let textStorage = NSTextStorage(string: myString)
let textContainer = NSTextContainer(size: CGSize(width: myWidth, height: CGFloat.max))
let layoutManager = NSLayoutManager()
layoutManager.addTextContainer(textContainer)
textStorage.addLayoutManager(layoutManager)
textStorage.addAttribute(NSFontAttributeName, value: myFont, range: NSMakeRange(0, textStorage.length))
textContainer.lineFragmentPadding = 0
textContainer.lineBreakMode = .ByWordWrapping
layoutManager.glyphRangeForTextContainer(textContainer)
return layoutManager.usedRectForTextContainer(textContainer).size.height
}
But the calculated height is wrong when the text contains an emoji.
var s = "ABCDE 12345"
print(calculateTextHeight(s, myWidth: 500, myFont: UIFont.systemFontOfSize(14)))
// prints 16.7 (correct)
s = "ABCDE 12345 💩"
print(calculateTextHeight(s, myWidth: 500, myFont: UIFont.systemFontOfSize(14)))
// prints 22.9 (should be 16.7)
Is this a bug? How can I fix this?
This worked for me when text contains emojis. For NSAttributedString
strings:
extension NSAttributedString {
func sizeOfString(constrainedToWidth width: Double) -> CGSize {
let framesetter = CTFramesetterCreateWithAttributedString(self)
return CTFramesetterSuggestFrameSizeWithConstraints(framesetter, CFRange(location: 0, length: 0), nil, CGSize(width: width, height: .greatestFiniteMagnitude), nil)
}
}
For String
:
extension String {
func sizeOfString(constrainedToWidth width: Double, font: UIFont) -> CGSize {
let attributes = [NSAttributedString.Key.font : font]
let attString = NSAttributedString(string: self, attributes: attributes)
let framesetter = CTFramesetterCreateWithAttributedString(attString)
return CTFramesetterSuggestFrameSizeWithConstraints(framesetter, CFRange(location: 0, length: 0), nil, CGSize(width: width, height: .greatestFiniteMagnitude), nil)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With