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?