Intrinsic content size of button with text only - ios

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

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

UILabel on second line if the content doesn't fit in the view's first line

The best way to describe my situations is with images. What I have is a view which contains several UILabels and UIImage. The red box is a UILabel and if the content is too big it should go to the second line.
From the storyboard I have a working case when the content fits but the problem is that I am not sure how to handle the case when the last (red box) should go to the second line. I am using autolayout and cartography.
If someone can point me to the right direction I will be very grateful.
First calcululate width of text as per your current label's position.
If text width is more than current label's width then see my answer from below link:
Auto Layout how to move the view2 from right to the bottom?
Calculate width:
func widthForView1(_ text:String, font:UIFont, height:CGFloat) -> CGFloat
{
let label:UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: your_label_width, height: your_lable_height))
label.numberOfLines = 0
label.lineBreakMode = NSLineBreakMode.byWordWrapping
label.text = text
label.font = font
label.sizeToFit()
return label.frame.width
}
You cannot do that with constraints only. To change the entire position of the element on the screen, you need to do it programmatically.
Use of tag View can solve this issue. TagListView is an external library.
When u add a view as subclass of taglistView, its height automatically increases accordingly.
ADD this to pod file : pod 'TagListView'
func addTags() {
let str1 = "Hi"
tagListView.addTag(str1)
let str2 = "Helloo"
tagListView.addTag(str2)
let str3 = "How Are u ? "
tagListView.addTag(str2)
tagListView.isUserInteractionEnabled = false
}

Adjust font size of text to fit in UIButton

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".

Adding multiple Lines of text into UILabel in swift

Hi I want to display some text in my UILabel line by line when an action is occurred
Hi, I have a textbox, button and a UILabel, lets say I've typed in
"This text will be displayed line by line in a UILabel"
and pressed the button to display the text in the UILabel..
so inside the UILabel it will look like:
This
text
will
be
displayed
line
by
line
in
a
UILabel
....
I've been searching forums but could not found an answer.. so I don't know if this is possible.. please help
p.s I've set number of lines to 0 and line breaks is set to word wrap
let label = UILabel(frame: CGRect(x: 100, y: 100, width: 100, height: 300)) // make the height biggest
// label.lineBreakMode = NSLineBreakMode.ByWordWrapping
// label.numberOfLines = 0
dont work if label width bigger word width
var string = "This text will be displayed line by line in a UILabel"
var array = string.componentsSeparatedByString(" ")
var newstring = join("\r", array)
label.text = newstring
let labelText = "Write\rthe\rtext\rwith\rline\rbreaks."
In order to wrap your text within a UILabel on Xcode 6 and above
Select the label you are working with.
Navigate to the Utilities panel.
Select the "Attributes inspector"
Select the number of lines you would like to display on the label (2,3,4) depending on the size of your UILabel field
Select "Word Wrap" under Line Breaks, or you can select any option of your preference.
You may manipulate the way your text appears to your taste.
Does it have to be a UILabel?
You could use UITextField instead which has some advantageous handling options

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