Skip to content

Instantly share code, notes, and snippets.

@KentarouKanno
Created February 6, 2019 02:00
Show Gist options
  • Save KentarouKanno/6ae84948f40f6ff37da790ff264517d1 to your computer and use it in GitHub Desktop.
Save KentarouKanno/6ae84948f40f6ff37da790ff264517d1 to your computer and use it in GitHub Desktop.
extension UILabel {
    
    /// NSAttributedStringを適用したラベルの高さを取得する(主にヒラギノのディセンダに対応する為)
    ///
    /// - Returns: ラベルの高さ
    func labelHeight() -> CGFloat {
        guard let attributes = self.attributedText else { return 0 }
        var labelHeight: CGFloat = 0
        let framesetter = CTFramesetterCreateWithAttributedString(attributes)
        let box: CGRect = CGRect(x: 0, y: 0, width: self.bounds.width, height: CGFloat.greatestFiniteMagnitude)
        
        let startIndex: CFIndex = 0
        let path: CGMutablePath = CGMutablePath()
        path.addRect(box)
        
        let frame: CTFrame = CTFramesetterCreateFrame(framesetter, CFRangeMake(startIndex, 0), path, nil)
        
        let lineArray: CFArray = CTFrameGetLines(frame)
        let lineCount: CFIndex = CFArrayGetCount(lineArray)
        var lineHeight: CGFloat = 0
        var ascent: CGFloat = 0
        var descent: CGFloat = 0
        var leading: CGFloat = 0
        
        for num in 0 ..< lineCount {
            let currentLine = unsafeBitCast(CFArrayGetValueAtIndex(lineArray, num), to: CTLine.self)
            CTLineGetTypographicBounds(currentLine, &ascent, &descent, &leading)
            lineHeight = ascent + descent + leading
            labelHeight += lineHeight
        }
        return labelHeight
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment