Adjust font size of text to fit in UIButton - ios

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) ?
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

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

Updated code for Swift 3.0:
yourButton.titleLabel?.minimumScaleFactor = 0.5
yourButton.titleLabel?.numberOfLines = 0
yourButton.titleLabel?.adjustsFontSizeToFitWidth = true

You can also set a User Defined Runtime Attribute in Interface Builder for the button where
titleLabel.adjustsFontSizeToFitWidth = true

to make text horizontally and vertically fit with button bounds :
1 - set button alignment like image (* VERY IMPORTANT *)
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 :

Try to call the following method.
button.titleLabel?.baselineAdjustment = UIBaselineAdjustment.AlignCenters

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

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

In Xcode->Open storyboard->Go to attributes inspector->Control->Alignment->Choose second in both horizontal and vertical.
or
YourButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;

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

Related

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

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?
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:
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)
}

Multiline UILabel with right-to-left text and auto adjusted font size

Below is the code in Swift I used for a 2 line UILabel with adjustsFontSizeToFitWidth set to true, working properly for left-to-right text. I have used EasyPeasy library for setting layout constraints.
let contactLabel = UILabel()
contactLabel.text = "Tell us how we can contact you".localized()
contactView.addSubview(contactLabel)
contactLabel.easy.layout([Leading(), Trailing(), Top(20), Height(60)])
contactLabel.numberOfLines = 2
contactLabel.lineBreakMode = .byTruncatingHead
contactLabel.adjustsFontSizeToFitWidth = true
When I changed the language to Arabic, the text will be broken to two lines properly but shown in LTR mode instead of RTL. How should manage a multiline label to show Arabic text?
I also checked this behavior on iOS 11 and it is working, maybe there is a trick to it in iOS 12.
Don't set a specific height because of that is not expanding to your amount of text.
Steps 1 - Set top, leading, trailing and height constraint and change height relation to Greater Than or Equal to
Step 2 - label.numberOfLines = 0
Step 3 - label.sizeToFit()
step 4 - label.lineBreakMode = .byTruncatingTail
Although setting the label alignment to "natural" works in most cases, iOS sometimes gets it wrong. If you're out of ideas, you can always set it manually in the code based on the current layout direction of the application.
if UIApplication.shared.userInterfaceLayoutDirection == .leftToRight {
resultLabel.textAlignment = .left
} else {
resultLabel.textAlignment = .right
}

Intrinsic content size of button with text only

I have a uibutton, i want to set text dynamically at run time with padding top: 10, bottom 10 and left: 10 and right: 10, once i set text button title cliped. Any one can provide solution.
You must be attentive to fontSize of the button. Setting text programmatically doesn't automatically fits the text. Following code will help you.
//Swift
let btnLabel = yourButton.titleLabel
btnLabel.adjustsFontSizeToFitWidth = true
//Objective C
UILabel *btnLabel = yourButton.titleLabel;
btnLabel.adjustsFontSizeToFitWidth = true
Happy Coding <3

How to scale the fonts in a Button

I'm trying to complete my first app in Swift and I met with the problem.
I have some buttons with the tittles and background image. Running the simulation on different devices makes them scale, so the tittles goes out of buttons frame.
There is no "Dynamic Type Automatically Adjust Font" checkbox in my Xcode attributes inspector so I made the custom UIButton class and made the inspectable var
#IBInspectable var adjustFontSize : Bool {
set { titleLabel?.adjustsFontForContentSizeCategory = newValue }
get { return titleLabel!.adjustsFontForContentSizeCategory }
but this does't helps and I got "Automatically adjusts font requires using a dynamic type text style" warning
So how can I make my button title scale to fit the Button frame when the button changes size and proportions on different devices?
This worked for me.
btn.titleLabel?.minimumScaleFactor = 0.1
btn.titleLabel?.numberOfLines = 1
btn.titleLabel?.adjustsFontSizeToFitWidth = true
Try these
button.titleLabel!.numberOfLines = 1
button.titleLabel!.adjustsFontSizeToFitWidth = true
button.titleLabel!.baselineAdjustment = .alignCenters
but for them to work, you will have to set button width constraint either in storyboard or programatically.
This will then make the title size change based on the width of the button.

How to change Button Title Alignment in Swift?

I am trying to set the title on a Button to left. But everything i tried is not working.
With:
UILabelButton.titleLabel.textAlignment = .Left
Or:
UILabelButton.contentVerticalAlignment = UIControlContentVerticalAlignment // There is no left
The button title is still centered.
Is there another Property?
Use contentHorizontalAlignment.You have to use UIControlContentHorizontalAlignment.Left.You need to usehorizontal not vertical.
btn.contentHorizontalAlignment = UIControlContentHorizontalAlignment.Left
Swift 3.x
btn.contentHorizontalAlignment = .left
Swift 4
Sample code
For my requirement I want alignment left top
btnAddress.contentHorizontalAlignment = UIControlContentHorizontalAlignment.left
btnAddress.contentVerticalAlignment = UIControlContentVerticalAlignment.top
Swift 5 update:
btnAddress.contentHorizontalAlignment = UIControl.ContentHorizontalAlignment.left
btnAddress.contentVerticalAlignment = UIControl.ContentVerticalAlignment.top
btnAddress.contentHorizontalAlignment = UIControl.ContentHorizontalAlignment.left
btnAddress.contentVerticalAlignment = UIControl.ContentVerticalAlignment.top
And now if you want the text to have some space from left add this
btnAddress.titleEdgeInsets = UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 0)
You can also use the below solution (using Storyboard)
step1 :
set the horizontal alignment to left
By default button property have left content inset set to 10 i.e padding for the button from left side
you can see in the below image the left content inset is set to 10 for Left
so change that to 0, if you don't need any padding from left or set the number you want
This way you can set the button title to Left aligned
like this with swift 4:
btnAddress.contentHorizontalAlignment = .center
The Most Easiest and smallest Solution:
Button("0"){}.frame(width:160.0,height:70.0,alignment:Alignment.leading)
Check this by using this code for a button you will see that button text is now aligned to "LEFT"

Resources