Auto shrink label with multiple lines Swift - ios

I am making a app without using storyboard. The app has a long text so I can't get enought space on one line. The app is for both iPad and iPhone. The adjustSizeToFit = true does not work, is there a metode to adjust size of label with multiple lines?

There is no property on UILabel called adjustSizeToFit. Are you sure you didn't mean adjustsFontSizeToFitWidth? Which if you look at the documentation, says:
Normally, the label text is drawn with the font you specify in the font property. If this property is set to true, however, and the text in the text property exceeds the label’s bounding rectangle, the receiver starts reducing the font size until the string fits or the minimum font size is reached. In iOS 6 and earlier, this property is effective only when the numberOfLines property is set to 1.
Which I'm not sure is what you wanted.
If you wanted a UILabel with an arbitrary number of lines, where the text is contained within a certain width, continue reading:
What you do will depend on whether you're using AutoLayout or not:
Not AutoLayout
Just use:
let size = label.sizeThatFits(CGSize(width: myWidth, height: CGFloat.max))
// CGFloat.max, because we don't want to limit the UILabel's height.
label.frame.size = size
AutoLayout
Firstly, you should set numberOfLines to zero.
Secondly, you need to tell AutoLayout how long each line can be, this doesn't default to the width of the label. For this you need a UILabel subclass:
class myLabel : UILabel {
override func layoutSubviews() {
// 1. Get the label to set its frame correctly:
super.layoutSubviews()
// 2. Now the frame is set we can get the correct width
// and set it to the preferredMaxLayoutWidth.
self.preferredMaxLayoutWidth = self.frame.width
}
}

Related

How to make UILabel resize to fit text

I have a UILabel that I have layed out in a storyboard centred in the view. It has some initial text "tap to login".
I am changing the value of the label to be the user's name once they have logged in. Once I do this, the label is no longer centered as the UILabel has not changed size.
How can I do this with autolayout in interface builder?
see this scrrenshot
1 first select your label width constraint
2 set the relation Greater than or equal
3 set the default constant value here i set it 10
when you change the label text it change the size of label according to its text. hope it's help :)
Iam guessing the label is not getting height and width, consider giving those constraints and then when your text changes use this method to determine the height and width:
func labelSizeWithString(text: String, maxWidth : CGFloat,numberOfLines : Int) -> CGRect{
let label = UILabel(frame: CGRectMake(0, 0, maxWidth, CGFloat.max))
label.numberOfLines = numberOfLines
label.text = text
label.sizeToFit()
return label.frame
}
You can set the UILabel frame.width bigger, maybe the same width as the screen.
Then you set the
label.textAlignment = NSTextAlignmentCenter
1.showing initial text to label
2.After pressing button changing text, that showing in middle of screen 3.Look at constraints third image, two constraints given 1.top to view 2.horizontally middle in container
Another thing if u given fixed width for the label,change relation as more than equal.[Click width constraint ,see right side top there change the relation

sizeToFit with maximum width

I am trying to programmatically manipulate a UILabel so that it has a dynamic width.
I found that using sizeToFit() does this exact behavior.
Now as this label becomes my navigationItem.titleView. I want it to have a maximum size, which can't be extended.
It is important to fit 2 barButtonItems in the navigationItem.
For instance: a backBarButton on the left, an addButton on the right.
Is there a way to change the sizeToFit() method?
You can use sizeThatFits: see docs here.
You have to specify a CGSize that you want to fit in.
to set maximum width use preferredMaxLayoutWidth than set the maximum size like that bounds.width - 120
for example:
yourLabel.sizeToFit()
yourLabel.numberOfLines = 0
yourLabel.preferredMaxLayoutWidth = bounds.width - 120

How do I change UILabel size depending on its font size?

#IBAction func sizeChanged(sender: UISlider) {
let senderValue = CGFloat(sender.value)
myLabel?.font = UIFont(name: (myLabel?.font.fontName)!, size:senderValue * 20)}
I want to change myLabel.font size with a slider, but myLabel does not change adjust its width and height as the font size increases.
How do I change the UILabel size to follow its font size?
Thanks.
After updating the font size of the UILabel, you'll want to call sizeToFit().
myLabel?.sizeToFit()
According to the UIView Class Reference,
Call this method when you want to resize the current view so that it uses the most appropriate amount of space. Specific UIKit views resize themselves according to their own internal needs. In some cases, if a view does not have a superview, it may size itself to the screen bounds. Thus, if you want a given view to size itself to its parent view, you should add it to the parent view before calling this method.
myLabel?.sizeToFit() will set the size of label to fit its content...just make sure you haven't added height and width constraints for the label.

UIButton with increasing height if width is not enough?

I need a button to set up via autolayout which height will increase if the horizontal space is not enough i.e. after rotation. I have a leading and trailing constraint to the parent view, and in portrait mode there is lack of space, so I was thinking about not to reduce font size, but increase height and set Word Wrap for Line Break. I was experimenting size classes, but in somehow always the wCompact hAny is used, because I am testing in iPhone. So to set different height for button for different size classes had no effect.
Anybody has idea how to set depending button height on the available button width and the content via autolayout constraint?
On iPhone button below needs two lines, not 30px, but appr. 60px.
Why are you using a button? This is not what a button is for. If you have that amount of text to display then use either a UILabel or UITextView. You can then add a gesture recogniser to it to capture the tap.
You can use UILabel and can use UITapGestureRecognizer on it. and set number of lines=0 in nib file and have one action of tap gesture. it will work like a button with almost no code as u want
Because I am suspicious it is not possible with Interface Builder I made it with subclassing an UIButton:
class DynamicHeightButton: UIButton {
override func layoutSubviews() {
super.layoutSubviews()
let size = (self.titleForState(UIControlState.Normal)! as NSString).boundingRectWithSize(CGSizeMake(self.bounds.size.width, CGFloat.max), options: NSStringDrawingOptions.UsesLineFragmentOrigin, attributes: [NSFontAttributeName : UIFont.systemFontOfSize(17)], context: nil)
self.bounds.size.height = size.height + 8
}
}

Autosize UILabel

Is there a way to auto size a UILabel? given size 40 x 40 the text font size would adjust based on the number of characters.
You can use the adjustFontSizeToFitWidth property. So something like this.
UILabel *myLabel = [[UILabel alloc] init];
[myLabel setAdjustsFontSizeToFitWidth:YES];
In Interface Builder there is a check box on the Label Attributes screen to allow you to adjust the font size to fit the label as well.
uhm, did you check out the UILabel API http://developer.apple.com/iphone/library/documentation/uikit/reference/UILabel_Class/Reference/UILabel.html there's a neat property called adjustsFontSizeToFitWidth
With autolayout design concept, do not set height constraints for UILabel and set no. of lines as 0.
Autolayout automatically take care of dynamic height of label according to text of label. If label has single line text then it will occupy single line space only. And if label has more than one line then it will resize label according to text size and number of lines required to display text.
Set number of lines zero for dynamic text information, it will be useful when your text are varying.
Programatically (Swift 4)
var label = UILabel()
let stringValue = "iOS\nmultiline\nlabel\nin\nInterface\nbuilder"
label.text = stringValue
label.numberOfLines = 0 // Set 0, if number of lines not specified.
label.lineBreakMode = .byTruncatingTail // or .byWrappingWord
label.minimumScaleFactor = 0.8 . // It is not required but nice to have a minimum scale factor to fit text into label frame
Using Inetrface Builder
Note: It is not required to set Minimum Font Scale, but nice to have a minimum scale factor to fit text into label frame.
Ref: UILabel - numberOfLines
Its better to use Intrinsic content and compression resistance priorities to adjust the size of label w.r.t content.

Resources