Adjust UIButton font size to width

I have the following code:

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(0.0, 0.0, 25, 25);

[[button layer] setCornerRadius:5.0f];
[[button layer] setMasksToBounds:YES];
[[button layer] setBackgroundColor:[[UIColor redColor] CGColor]];
[button.titleLabel setFrame:CGRectMake(0,0, 25, 25)];

[button setTitle:[NSString stringWithFormat:@"%@", [[topics objectAtIndex:indexPath.row] unread]] forState:UIControlStateNormal];

The issue is that when the string in the text is not long, it shows fine (1-2 digit). However, when it's quite long (3++ digit), all I can see is a red button, with no text inside. How do I adjust this?

I don't think that:

[button.titleLabel setAdjustsFontSizeToFitWidth:YES];

does the job, right?


Solution 1:

Try this:

button.titleLabel?.numberOfLines = 1
button.titleLabel?.adjustsFontSizeToFitWidth = true
button.titleLabel?.lineBreakMode = .byClipping //<-- MAGIC LINE

I'm not sure why this does the trick but it does :)

Solution 2:

button.titleLabel.adjustsFontSizeToFitWidth = YES;

should do the work on its own if you are using Auto-Layout and have set a constraint on the button's width.

The other options (minimum scale factor, number of lines etc) can still be used to customize further according to your needs, but are not required.

Solution 3:

The answer from EliBud doesn't work on iOS 8. I found a solution which works on iOS 8. Below is a swift code:

let label = self.button?.titleLabel
label?.minimumScaleFactor = 0.01
label?.adjustsFontSizeToFitWidth = true
label?.font = UIFont.systemFontOfSize(100)

You can play with label?.lineBreakMode as I found that results varies for different break modes.

Solution 4:

Swift 4 extension

extension UIButton {
    @IBInspectable var adjustFontSizeToWidth: Bool {
        get {
            return self.titleLabel?.adjustsFontSizeToFitWidth
        }
        set {
            self.titleLabel?.numberOfLines = 1
            self.titleLabel?.adjustsFontSizeToFitWidth = newValue;
            self.titleLabel?.lineBreakMode = .byClipping;
            self.titleLabel?.baselineAdjustment = .alignCenters 
        }
    }
}

enter image description here