uikitnsattributedstringuigraphicscontext

Manually calculate font size for drawn NSAttributedString based on container width


UILabel has the property adjustsFontSizeToFitWidth which calculates the perfect font size if the bounding box is smaller than what text can be displayed at the current font size.

I am drawing text on a UIGraphicsImageRendererContext which is then exported to an image. I would like to recreate the behavior of adjustsFontSizeToFitWidth with the NSAttributedStrings I am currently using. This is the code I use to draw:

let text = NSAttributedString(string: "Example Text", attributes: [NSAttributedString.Key.font: font.withSize(16)])
text.draw(in: CGRect(x: 100, y: 100, width: 100, height: 20))

Is there a way to calculate the perfect font size based on the available width? I assume this would be an algorithm?


Solution

  • I achieved this by finding the scale factor by diving the smaller container width with the proposed string width, then using that scale factor to determine a new font size.

    var title = NSAttributedString(string: "Example", attributes: [NSAttributedString.Key.font: font.withSize(fontSize)])
    
    let titleWidth = title.size().width
    if titleWidth > containerWidth {
      let scaleFactor = containerWidth / titleWidth
      title = NSAttributedString(string: title.string, attributes: [NSAttributedString.Key.font: font.withSize(fontSize * scaleFactor)])
    }
    title.draw(in: CGRect(x: 100, y: 100, width: containerWidth, height: containerHeight))