Multiline UILabel with adjustsFontSizeToFitWidth

前端 未结 8 1495
北海茫月
北海茫月 2020-12-04 12:16

I have a multiline UILabel whose font size I\'d like to adjust depending on the text length. The whole text should fit into the label\'s frame without truncating it.

8条回答
  •  無奈伤痛
    2020-12-04 12:59

    There is an ObjC extension provided in comments, that calculate fontsize required to fit multiline text into UILabel. It was rewritten in Swift (since it is 2016):

    //
    //  NSString+KBAdditions.swift
    //
    //  Created by Alexander Mayatsky on 16/03/16.
    //
    //  Original code from http://stackoverflow.com/a/4383281/463892 & http://stackoverflow.com/a/18951386
    //
    
    import Foundation
    import UIKit
    
    protocol NSStringKBAdditions {
        func fontSizeWithFont(font: UIFont, constrainedToSize size: CGSize, minimumScaleFactor: CGFloat) -> CGFloat
    }
    
    extension NSString : NSStringKBAdditions {
        func fontSizeWithFont(font: UIFont, constrainedToSize size: CGSize, minimumScaleFactor: CGFloat) -> CGFloat {
            var fontSize = font.pointSize
            let minimumFontSize = fontSize * minimumScaleFactor
    
    
            var attributedText = NSAttributedString(string: self as String, attributes:[NSFontAttributeName: font])
            var height = attributedText.boundingRectWithSize(CGSize(width: size.width, height: CGFloat.max), options:NSStringDrawingOptions.UsesLineFragmentOrigin, context:nil).size.height
    
            var newFont = font
            //Reduce font size while too large, break if no height (empty string)
            while (height > size.height && height != 0 && fontSize > minimumFontSize) {
                fontSize--;
                newFont = UIFont(name: font.fontName, size: fontSize)!
    
                attributedText = NSAttributedString(string: self as String, attributes:[NSFontAttributeName: newFont])
                height = attributedText.boundingRectWithSize(CGSize(width: size.width, height: CGFloat.max), options:NSStringDrawingOptions.UsesLineFragmentOrigin, context:nil).size.height
            }
    
            // Loop through words in string and resize to fit
            for word in self.componentsSeparatedByCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet()) {
                var width = word.sizeWithAttributes([NSFontAttributeName:newFont]).width
                while (width > size.width && width != 0 && fontSize > minimumFontSize) {
                    fontSize--
                    newFont = UIFont(name: font.fontName, size: fontSize)!
                    width = word.sizeWithAttributes([NSFontAttributeName:newFont]).width
                }
            }
            return fontSize;
        }
    }
    

    Link to full code: https://gist.github.com/amayatsky/e6125a2288cc2e4f1bbf

提交回复
热议问题