LoginSignup
0
0

More than 5 years have passed since last update.

UIFont extension for the optimal fitting of text in a fixed size rectangle

Last updated at Posted at 2018-11-22

Instead of fitting a layout object to contain a text label of fixed size, it is sometimes required to fit the text inside a fixed layout.

In this particular case, we iteratively change the font until it converges on an optimized fit using the instantaneous aspect ratio of the label text. This helps to ensure the label fills the available space as much as possible.

extension UIFont {
    static func createFittedFont(maxWidth: CGFloat, maxHeight: CGFloat, text: String, fontName: String) -> UIFont? {

        let defaultSize: CGFloat = 20
        guard var font = UIFont(name: fontName, size: defaultSize) else {
            print("Error: invalid font name")
            return nil
        }

        let defaultWidth = text.width(withConstraintedHeight: CGFloat.greatestFiniteMagnitude, font: font)
        let defaultHeight = text.height(withConstrainedWidth: CGFloat.greatestFiniteMagnitude, font: font)
        let defaultAspectRatio = defaultHeight / defaultWidth
        let targetAspectRatio = maxHeight / maxWidth

        let eta: CGFloat = 0.03
        let coefficient: CGFloat = 0.4

        while (true) {
            let delta = (targetAspectRatio < defaultAspectRatio) ?
                maxHeight / text.height(
                    withConstrainedWidth: CGFloat.greatestFiniteMagnitude, 
                    font: font) - 1.0
                :
                maxWidth / text.width(
                    withConstraintedHeight: font.pointSize, 
                    font: font) - 1.0

            if(fabs(delta) <= eta) { break }
            let newSize = font.pointSize * (1.0 + coefficient * delta)
            font = font.withSize( newSize )
        }

        return font
    }
}```
0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0