How to scale the button text based on screen design swift?

1.3k views Asked by At

In my project, i am using scaling for UI components. I am able to scale the text for UIlabel like below and it's working in all device:

1. Autoshrinks - minimum font scale set it to 0.5

2. No of lines - 0

3. Enable dynamic type in attribute inspector

4. adjustFontSizeToWidth to true

But when i am trying to adjust font for UI Button using beolow steps and i am not able to scale the text for UI button.

button.titleLabel?.numberOfLines = 1 // Tried with 0 also

button.titleLabel?.adjustsFontSizeToFitWidth = true

button.titleLabel?.lineBreakMode = // tried differenet linebreakmode

Could anyone have an idea of scaling UI Button text?

2

There are 2 answers

4
DonMag On BEST ANSWER

Are you sure it's not working?

Edit - After comments...

UIKit elements such as UILabel / UIButton / etc to not have a built-in "auto-adjust font height" property.

I don't work for Apple, so just guessing that is (at least in part) due to the fact that, in general...

Based on screen height, the UI is designed to either:

  • provide more or less information, e.g. more rows in a table, or
  • adjust vertical spacing between elements

That doesn't mean you can't or shouldn't adjust your font sizes... it just means you have to do it manually.

Couple options:

  • set the font-size at run-time, as suggested by Duncan
  • use a UIAppearance proxy to set the font-size, again at run-time

in either case, you could use a height-to-fontSize table or a "percentage" calculation.

Another option would be a custom class that sets the font-size based on the constrained button height.

Here's a simple example (note: for demonstration purposes only):

class AutoFontSizeButton: UIButton {
    
    override func layoutSubviews() {

        super.layoutSubviews()

        guard let fnt = titleLabel?.font else { return }

        // default system type button has 6-pts top / bottom inset
        //  and font size is 15/18ths of that height
        let h = ((bounds.height - 12.0) * (15.0 / 18.0)).rounded()
        let fs = fnt.pointSize

        if h != fs {
            titleLabel?.font = UIFont(descriptor: fnt.fontDescriptor, size: h)
        }

    }

}

Result - the top three (yellow) buttons are 30, 40 and 50-points in height, with the default font-size of 15. The bottom three (green) buttons are again 30, 40 and 50-points in height, but the font-size is automatically set at run-time:

enter image description here

0
Duncan C On

I don't think there is a way to get the font to auto-size. However, if you set the button's titleLabel.font to a specific font size the button will update to use the new font size, including resizing the button.

Use code like this:

            let size: CGFloat = useLargeFont ? 50.0 : 17.0  //Change as needed
            if let buttonFont = button.titleLabel?.font {
                button.titleLabel?.font = buttonFont.withSize(size)
            }