40

I want to make sure the button text fits into a UIButton, while the UIButton has a fixed size.

Of course I can access the titleLabel of the UIButton. In a label I would set autoshrink to minimum font scale which seems to correspond to

self.myButton.titleLabel.adjustsFontSizeToFitWidth = YES;

, but doesn't really behave the same, since it only makes the text fits horizontally into the bounds, not vertically, thereby not changing the font size.

How can i actually adjust the font size of a label programmatically to make the text fit into the label bounds (as shown in Goal in the picture below) ?

adjustsFontSizeToFitWidth does not actually adjust the font size to fit the frame, only the width

I already tried

self.myButton.titleLabel.numberOfLines = 0;
self.myButton.titleLabel.minimumScaleFactor = 0.5f;

without success, always ended up as in adjustsFontSizeToFitWidth on the left side of the pic above.

Edit: The solution also has to be ios7 compliant

MarkHim
  • 5,686
  • 5
  • 32
  • 64

9 Answers9

94
self.mybutton.titleLabel.minimumScaleFactor = 0.5f;
self.mybutton.titleLabel.numberOfLines = 0;   <-- Or to desired number of lines
self.mybutton.titleLabel.adjustsFontSizeToFitWidth = YES;

... did the trick, after layoutIfNeeded in viewDidLoad As it turns out, all those must be set to actually adjust the font-size, not just making it fit into the frame.

Update for Swift 3:

mybutton.titleLabel?.minimumScaleFactor = 0.5
mybutton.titleLabel?.numberOfLines = 0   <-- Or to desired number of lines
mybutton.titleLabel?.adjustsFontSizeToFitWidth = true
ToolmakerSteve
  • 18,547
  • 14
  • 94
  • 196
MarkHim
  • 5,686
  • 5
  • 32
  • 64
  • 10
    I had to set self.myButton.titleLabel.numberOfLines = 1; otherwise there can be two lines. – Vladimír Slavík May 25 '16 at 14:11
  • 1
    @MarkHim I have the situation that the text fits horizontally in button, but not vertically. In that situation it doesn't´t work ;-( Any ideas? – mica Nov 02 '17 at 16:53
  • 2
    Sounds like you have hard height constraints @mica i assume the intrinsic content size should be calculated correctly with my method, so just remove the height constraint and it should work fine – MarkHim Nov 23 '17 at 08:43
  • 2
    I had to add `self.mybutton.titleLabel.lineBreakMode = NSLineBreakByClipping` for this answer to work – AnthoPak Apr 10 '18 at 08:17
11

You can also set a User Defined Runtime Attribute in Interface Builder for the button where

titleLabel.adjustsFontSizeToFitWidth = true
Sangram Shivankar
  • 3,535
  • 3
  • 26
  • 38
StackUnderflow
  • 2,403
  • 2
  • 21
  • 28
  • 1
    Indeed this is the correct answer. Be sure to not have Word Wrap (then it doesn't work) but to have Truncate Trailing or such. You can also have a number for titleLabel.minimumScaleFactor; but the titleLabel.adjustsFontSizeToFitWidth must be there. Hit the + sign on the User Defined Attributes in the Identity Inspector in Interface Builder while the Button is selected. Thanks @StackUnderflow. – codeslapper Jul 24 '18 at 19:33
11

Updated code for Swift 3.0:

yourButton.titleLabel?.minimumScaleFactor = 0.5
yourButton.titleLabel?.numberOfLines = 0
yourButton.titleLabel?.adjustsFontSizeToFitWidth = true
Sangram Shivankar
  • 3,535
  • 3
  • 26
  • 38
CodeBender
  • 35,668
  • 12
  • 125
  • 132
6

to make text horizontally and vertically fit with button bounds :

1 - set button alignment like image (* VERY IMPORTANT *)

enter image description here

2 - add this lines of code in your ViewController

btnTest.setTitle("Test for multi line in button show line in button show Test for multi line in button show line in button show", for: .normal)
btnTest.titleLabel!.textAlignment = .center
btnTest.titleLabel!.numberOfLines = 0
btnTest.titleLabel!.adjustsFontSizeToFitWidth = true
btnTest.titleLabel!.minimumScaleFactor = 0.5
// below line to add some inset for text to look better
// you can delete or change that
btnTest.contentEdgeInsets = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
  • note that DON'T using btnTest.titleLabel!.lineBreakMode = NSLineBreakMode.byWordWrapping or other BreakMode in your code . for enable multiline in button . just using from above code

final result :

enter image description here

Hamid Reza Ansari
  • 1,107
  • 13
  • 16
3

Try to call the following method.

button.titleLabel?.baselineAdjustment = UIBaselineAdjustment.AlignCenters
Jason Nam
  • 2,011
  • 2
  • 13
  • 22
2

In Storyboard, Go to Link Break in Attributes Inspector, see word wrap..or set according to your choice.

Clean Coder
  • 496
  • 5
  • 12
1

try this:

  [myButton setFont:[[myButton font] fontWithSize:--originalButtonFontSize]];
  textWidth = [text sizeWithFont:[myButton font]].width;

}
Sangram Shivankar
  • 3,535
  • 3
  • 26
  • 38
Wostein
  • 11
  • 2
0

In Xcode->Open storyboard->Go to attributes inspector->Control->Alignment->Choose second in both horizontal and vertical.

or

YourButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
VJVJ
  • 435
  • 3
  • 21
-2

If you prefer do in storyboard, just click the button, then show attributes inspector, and set the line break to "Word Wrap".

word wrap

Sonic Master
  • 1,238
  • 2
  • 22
  • 36