Text alignment in UIlabels - ios

I have 2 adjacent labels of same width. label1 text takes only one line. Text for label2 is long,
objective is to show full text in 2 lines,
I am using label.numberOfLines = 2 and adjustsFontSizeToFitWidth = YES;
Now, first line of label2 is not aligned with first line of label1. while labels are still aligned, label2 text is starting with a margin inside label. I wanted label2 text to start from top.
please help me with this.

Fixed:
CGSize originalSize = [label.text sizeWithAttributes:#{NSFontAttributeName:label.font}];
CGFloat usedScaleFactor = label.frame.size.width / originalSize.width;
CGFloat newFontSize = label.font.pointSize * usedScaleFactor;
label.font = [UIFont fontWithName:#"fontName" size:newFontSize];
This fixed my issue. iOS was calculating label frame with my original text font size while changing my text font due to adjustsFontSizeToFitWidth...
Hope this helps someone who is searching this..

Related

Calculate where text starts on centre alignment

I have a UILabel that I want to add a UIView exactly where the text starts.
The problem is that the text in the label is aligned to the centre so I don't know how to determinate where the actual text starts and where to position this UIView.
Any idea how can I calculate this thing?
Thank you!
You can use a UIView container which will wrap the UILabel and your new UIView. Then you can let the UILabel decides the width depending on its content and set it in the center of the container. Once you have this working you can just read the UILabel x to understand where it starts.
so the UILabel will have the constraints to top, bottom, the height you want and at center to horizontal whereas the little UIView to top, bottom, height, width and leading equal to UILabel
From :How to find the position(x,y) of a letter in UILabel
NSRange range = [#"Good,Morning" rangeOfString:#","];
NSString *prefix = [#"Good,Morning" substringToIndex:range.location];
CGSize size = [prefix sizeWithFont:[UIFont systemFontOfSize:18]];
CGPoint p = CGPointMake(size.width, 0);
NSLog(#"p.x: %f",p.x);
NSLog(#"p.y: %f",p.y);
you can modify it for your purpose
you can get text size using "nsattributedstring"
let label = UILabel(frame: CGRectMake(0, 0, 100, 100))
label.text = "dshfk,j"
label.textAlignment = .Center
label.textColor = UIColor.redColor()
let string = label.attributedText
let width = string!.size().width
let height = string!.size().height
let view = UIView(frame: CGRectMake(width, height, width, height))
view.backgroundColor = UIColor.blackColor()
then you can find rect using this ..
sample view
You could also use
yourLabel.sizeToFit()
to automatically resize your label for the space it needs. And then read out the frame of your label with:
yourLabel.frame.size (width or height)

iOS Swift UITextfield adjust fontsize width

How to adjust UITextfield font size when it is hold long character?
I tried adjustsFontSizeToFitWidth. it is not working.
any help will be appricated.thanks in advance
With a UITextField, text must fit on one line and cannot wrap.
You have two options:
Shrink the font to fit on one line:
self.TextFieldExample.adjustsFontSizeToFitWidth = YES;
self.TextFieldExample.minimumFontSize = 10.0; //Optionally specify min size
Use UITextView to enable text wrapping:
Working Swift 4 Solution
Make sure you set adjustsFontSizeToFitWidth to true and then set your minimumFontSize. This will scale the text inside the UITextField to fit the width of your UITextField with a minimum font size equal to or greater than what you set minimumFontSize to. When the text is still too long to scale down to fit at the minimum font size it will truncate the rest.
textField.adjustsFontSizeToFitWidth = true
textField.minimumFontSize = 10
You have to set the width first
textField.frame = CGRect(0, 0, your width, your height)
And
textField.minimumFontSize = 0.5

Make background UILabel bigger

I have a question in my app I have a number label (IBOutlet). And when I write self.numberLabel.backgroundColor = [UIColor redColor]; is showing a red color fit in the height of number, All I want is to make the background a little bit bigger. Thanks
self.numberLabel.frame = CGRectMake(self.numberLabel.frame.origin.x, self.numberLabel.frame.origin.y, widht, newHeight);
and to make sure font stay same size if needed
[self.numberLabel setFont:[UIFont systemFontOfSize:35]];
You have to set constraints in Interface Builder / Storyboard to fix your label height/width.
If your label's content changes in width, you can use this to calculate a new width with a bit of space left:
float labelWidth =
[self.myLabel.text
boundingRectWithSize:self.myLabel.frame.size
options:NSStringDrawingUsesLineFragmentOrigin
attributes:#{ NSFontAttributeName:self.myLabel.font }
context:nil]
.size.width;
CGRect rect = self.myLabel.bounds;
rect.size.width = labelWidth + 15.0f; //replace 15.0F with the value you want
[self.myLabel setBounds:rect];
There're many ways to skin a cat... in my case the content of the "uilabel" determines its size. I just want the background to be slightly bigger -- 5 points vertically, 7 points horizontally. So I use autolayout to solve it.
Add a uilabel as a subview to the background which is a uiview
Add constraints in IB between the uilabel and the uiview
Add constraints in IB between the uiview and its superview

Positioning a UILabel directly beneath another UILabel

I have an addition to NSString which automatically resizes a UILabel depending on the text that's being read into it (I have a simple app showing quotations, so some are a few words, some a couple sentences). Below that quote label, I also have an author label, which (oddly enough) has the author of the quote in it.
I'm trying to position that author label directly beneath the quote label (as in, its y coordinate would be the quote label's y coordinate plus the quote label's height. What I'm seeing is some space being placed between the two labels, that depending on the length of the quote, changes size. Smaller quotes have more space, while longer quotes have less space. Here's a quick diagram of what I'm seeing:
Note the gap between the red and blue boxes (which I've set up using layer.borderColor/borderWidth so I can see them in the app), is larger the shorter the quote is.
If anyone can sift through the code below and help point me towards exactly what's causing the discrepancy, I'd be really grateful. From what I can see, the author label should always be 35 pixels beneath the quote label's y + height value.
Just to confirm: everything is hooked up correctly in Interface Builder, etc. The content of the quote's getting in there fine, everything else works, so it's hooked up, that isn't the issue.
To clarify, my question is: Why is the gap between the labels changing dependant on the quote's length, and how can I get a stable, settable gap of 35 pixels correctly?
Here's the code I'm using to position the labels:
// Fill and format Quote Details
_quoteLabel.text = [NSString stringWithFormat:#"\"%#\"", _selectedQuote.quote];
_authorLabel.text = _selectedQuote.author;
[_quoteLabel setFont: [UIFont fontWithName: kScriptFont size: 28.0f]];
[_authorLabel setFont: [UIFont fontWithName: kScriptFontAuthor size: 30.0f]];
// Automatically resize the label, then center it again.
[_quoteLabel sizeToFitMultipleLines];
[_quoteLabel setFrame: CGRectMake(11, 11, 298, _quoteLabel.frame.size.height)];
// Position the author label below the quote label, however high it is.
[_authorLabel setFrame: CGRectMake(11, 11 + _quoteLabel.frame.size.height + 35, _authorLabel.frame.size.width, _authorLabel.frame.size.height)];
Here's my custom method for sizeToFitMultipleLines:
- (void) sizeToFitMultipleLines
{
if (self.adjustsFontSizeToFitWidth) {
CGFloat adjustedFontSize = [self.text fontSizeWithFont: self.font constrainedToSize: self.frame.size minimumFontSize: self.minimumScaleFactor];
self.font = [self.font fontWithSize: adjustedFontSize];
}
[self sizeToFit];
}
And here's my fontSizeWithFont:constrainedToSize:minimumFontSize: method:
- (CGFloat) fontSizeWithFont: (UIFont *) font constrainedToSize: (CGSize) size minimumFontSize: (CGFloat) minimumFontSize
{
CGFloat fontSize = [font pointSize];
CGFloat height = [self sizeWithFont: font constrainedToSize: CGSizeMake(size.width, FLT_MAX) lineBreakMode: NSLineBreakByWordWrapping].height;
UIFont *newFont = font;
// Reduce font size while too large, break if no height (empty string)
while (height > size.height && height != 0 && fontSize > minimumFontSize) {
fontSize--;
newFont = [UIFont fontWithName: font.fontName size: fontSize];
height = [self sizeWithFont: newFont constrainedToSize: CGSizeMake(size.width, FLT_MAX) lineBreakMode: NSLineBreakByWordWrapping].height;
};
// Loop through words in string and resize to fit
for (NSString *word in [self componentsSeparatedByCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]]) {
CGFloat width = [word sizeWithFont: newFont].width;
while (width > size.width && width != 0 && fontSize > minimumFontSize) {
fontSize--;
newFont = [UIFont fontWithName: font.fontName size: fontSize];
width = [word sizeWithFont: newFont].width;
}
}
return fontSize;
}
After you called size to fit on both labels, calculate the distance between their frames and change them accordingly:
[quoteLabel sizeToFit];
[authorLabel sizeToFit];
float distance = authorLabel.frame.origin.y - quoteLabel.frame.size.height;
float difference = distance - 35;
authorLabel.frame = CGRectMake(authorLabel.frame.origin.x,(authorLabel.frame.origin.y - difference),authorLabel.frame.size.width,authorLabel.frame.size.height);
The reason the gap changes is that the quote label frame changes its height dependent on its content when you call sizeToFit.
UPDATE
Given the recent developments in the comments, I think you have 3 possibilities:
resize the whitespace instead of only the words, so that the string
actually fits in the frame correctly
somehow access the CTFramesetter of UILabel to see what the actual
frame, when all is said and done, amounts to
make your own UIView subclass that handles Core Text drawing in its
draw rect method (should be easy in your case), since after all you
are trying to give to UILabel a behavior that it's not meant for
It probably is moving where you want it, but then an auto-layout constraint or a spring/strut is moving it afterwards.
EDIT:
My first thought (which I ruled out because you said that the box around the words was the label frame. In later comments, you say that this is not an actual screen shot, but just a representation of it, so it could still be correct) was that you are doing this wrong:
[_quoteLabel sizeToFitMultipleLines];
[_quoteLabel setFrame: CGRectMake(11, 11, 298, _quoteLabel.frame.size.height)];
In the first line, you are sizing the text to fit in whatever the current width of the label might be, and then you turn around in the second line and change the width of the label. So most likely, what is happening is that you are sizing the label for some smaller width, which makes it tall. You then make the label wider than it was before and the text expands to fit the wider label, leaving a blank area beneath the actual text, although the frame has not changed. This makes the space betwee the labels exactly 35 as you want, however the top label's text does not go all of the way to the bottom of its frame so the white space is more than you want. Basically, you have this:
*************
* text text *
* text text *
* *
* *
* *
*************
*************
* text text *
*************
If this is the case, then you would fix it by setting the width first, like this:
// You could put anything for the 200 height since you will be changing it in the next line anyway.
[_quoteLabel setFrame: CGRectMake(11, 11, 298, 200];
[_quoteLabel sizeToFitMultipleLines];
I ended up solving the problem by using a single UILabel, and CoreText with an NSAttributedString. Kind of a cop-out, but it works.

iOS multiline label in Interface builder

How can I make a multiline UILabel in interface builder for iOS? I tried the UITextView but it didn't quite suit my needs.
How can I add multiline (text) in label?
You can use numberOfLines property which defines maximum number of lines a label can have. By default, it's 1. Setting it to 0 means the label will have unlimited lines.
You can do it in code:
textLabel.numberOfLines = 5 // for example
Or in Interface Builder:
Hit Control+Enter to add a line in UILabel in Interface Builder/Storyboard.
Thanks AppleVijay!
Also to call sizeToFit, like this:
label.lineBreakMode = UILineBreakModeWordWrap;
label.numberOfLines = 0;
[label sizeToFit];
The height will be automatically computed.
set width of label as u needed small then use IB to set line breaks to word wrap
or use with code like this
I found a solution.
One just has to add the following code:
textLabel.lineBreakMode = NSLineBreakByWordWrapping;
textLabel.numberOfLines = 0;
Set number of lines zero for dynamic text information, it will be useful when your text are varying.
Programatically (Swift 3)
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.
Number of lines is visible in IB with Plain UILabels
set lines field as 0 . It will create multiple lines as per the provided space to the label.
In iOS7 (Xcode5) you shold set the lines of UILabel to 0 for unlimited multiple input in storyboard.
The most important is to set the height of the UILabel can hold the lines of input you are going to set.
textLabel.lineBreakMode = UILineBreakModeWordWrap;
textLabel.numberOfLines = 0;
CGSize size = [[[arrNewsFeed objectAtIndex:row] objectForKey:#"c"] sizeWithFont:[UIFont systemFontOfSize:14.0] constrainedToSize:CGSizeMake(188, CGFLOAT_MAX)
lineBreakMode:NSLineBreakByTruncatingTail];
textLabel.frame = (CGRect){.origin = cell.lblNewsDescription.frame.origin, .size = size};
If you set the numberOfLines property equal to 0, the label will automatically adjust to the required number of lines of the given text.
I had been struggling with this for a long time.
I just wanted my label text to appear on the second line. But whatever I do, it would just overflow the UILabel box. For me, changing the autoresizing in size inspector worked. Simple fix.
May be someone might find it helpful who is looking for something similar.
For X-Code 7.2
-- Select UILabel
-- Attributes inspector
-- Text - Select Attributed
After this you can see some more attribute you can add into you label, in which you can also find number of Lines. Which make your label multiline.

Resources