UILabel shows fewer lines then expected with multiple lines mode - ios

I'd like my UILabel to show my data in multiple lines, and the data is fetch from txt file.
I've searched online for this question, and all the answers show that I just need to set lineBreakMode to NSLineBreakByWordWrapping and numberOfLines = 0. However, the problem is that, even though I added these settings, the labels shows fewer lines than expected (my data has 4 lines, however the label only shows 2 lines). Here's my code:
-(void)updateFileContentLabel:(NSString*)content{
self.fileContentLabel.text = content;
self.fileContentLabel.lineBreakMode = NSLineBreakByWordWrapping;
self.fileContentLabel.font = [UIFont systemFontOfSize:17.0f];
self.fileContentLabel.numberOfLines = 0;
[self.fileContentLabel sizeToFit];
NSLog(#"file Label: %#",self.fileContentLabel.text);
}
As you see, I have a NSLog to show the content of label's text. And the text of label in NSLog is correct (4 lines). However on the phone or simulator, it only shows 2 lines instead of 4. Does anyone know where is the problem? Thanks!

Probably your UILabel is just not big enough. Solutions:
1.Increase a label size.
2.Add following code to allow UILabel to decrease the font size if needed.
self.fileContentLabel.minimumScaleFactor = 0.5;

I was only able to replicate your problem when I was using auto layout and didn't have constraints set up for fileContentLabel, so check that out.

Use the following method to calculate the height of text and set the frame of label accordingly.
- (CGSize)boundingSizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size lineBreakMode:(NSLineBreakMode)lineBreakMode
{
CGSize stringSize;
if ([self respondsToSelector:#selector(boundingRectWithSize:options:attributes:context:)]) {
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineBreakMode = lineBreakMode;
NSDictionary * stringAttributes = #{ NSFontAttributeName: font, paragraphStyle: NSParagraphStyleAttributeName};
stringSize = [self boundingRectWithSize:size
options:NSStringDrawingUsesLineFragmentOrigin
attributes:stringAttributes context:nil].size;
stringSize = CGSizeMake(ceil(stringSize.width), ceil(stringSize.height) + 2);
} else {
stringSize = [self sizeWithFont:font constrainedToSize:size lineBreakMode:lineBreakMode];
}
return stringSize;
}

Related

Scrolling to the end of UITextView's text

I have some contents in a view (such as images, labels) and the last item is a description (UITextView). Now I am trying to scroll the contents dynamically based on UITextView text. Here is my code:
- (void)viewDidAppear:(BOOL)animated {
_descriptions.scrollEnabled = NO;
[_descriptions sizeToFit];
_infoScrollView.contentSize = CGSizeMake(_contentsOnInfoView.frame.size.width,
_contentsOnInfoView.frame.size.height + _descriptions.frame.size.height);
}
Here is the result:
As you can see, there is lots of empty space. I need to scroll to the end of text.
I'd suggest you to try this.
[myTextView scrollRangeToVisible:NSMakeRange([myTextView.text length], 0)]
You should write you code in
-(void) viewDidLayoutSubviews {}
In this method,All components have frame according to running device size. and execute before appear the view.
//may be it will work for you
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc]init];
//set the line break mode
paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
NSDictionary *attrDict = [NSDictionary dictionaryWithObjectsAndKeys: description.font,
NSFontAttributeName,
paragraphStyle,
NSParagraphStyleAttributeName,
nil];
CGRect rect = [description.text boundingRectWithSize:CGSizeMake(description.size.width, FLT_MAX)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:attrDict
context:nil];
CGSize size = rect.size;
_infoScrollView.contentSize = CGSizeMake(_contentsOnInfoView.frame.size.width,description.frame.origin.y + size.height + 20)
I just found the answer,in the UI there is line that separates descriptions with the some infos ! I just calculate the line's y and sum up with the descriptions height :
_descriptions.scrollEnabled = NO;
[_descriptions sizeToFit];
_infoScrollView.contentSize = CGSizeMake(_infoView.frame.size.width, _line.frame.origin.y + _descriptions.bounds.size.height);
now it works fine !

UILabel Text Multi Line given width of text

I want to scale a UILabel exactly how snapchat does. I have a textfield where I insert the text. When tapping done the textfield goes and the label's text is set. I want to insert multiple lines when the text is larger than width of screen and truncate the frame of label so that the text fits.
Here is my code
if(isCaption){
//Begin Edit Text
_textlabel.hidden = NO;
_textlabel.text = currentText;
_textFieldOutlet.hidden = YES;
[_textFieldOutlet setTextAlignment:NSTextAlignmentLeft];
[_textlabel setTextAlignment:NSTextAlignmentLeft];
[self.screenShotView bringSubviewToFront:_textlabel];
_textlabel.frame = CGRectMake(10,
_textlabel.frame.origin.y,
[currentText sizeWithAttributes:#{NSFontAttributeName:[_textlabel font]}].width,
[currentText sizeWithAttributes:#{NSFontAttributeName:[_textlabel font]}].height);
isEditing = YES;
isCaption = NO;
}
The problem is that the result is a huge line of text and I want it spreads on multiline. How can this be accomplished? How can I separate the lines given width?
If you want multiple lines you should not calculate your width with sizeWithAttributes: . You should fix your width for the label and then calculate the height with boundingRectWithSize: method.
You can create a helper method as follows:
- (CGSize)suggestedSizeWithFont:(UIFont *)font size:(CGSize)size lineBreakMode:(NSLineBreakMode)lineBreakMode forString:(NSString *)text {
NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
paragraphStyle.lineBreakMode = lineBreakMode;
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:text attributes:#{NSFontAttributeName: font, NSParagraphStyleAttributeName: paragraphStyle}];
CGRect bounds = [attributedString boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin context:nil];
return bounds.size;
}
Or you can create a category and get rid of that extra text parameter.
Then you can call the method for you label's text as follows:
CGSize requiredSize = [self suggestedSizeWithFont:_textLabel.font size:CGSizeMake(self.view.frame.size.width, CGFLOAT_MAX) lineBreakMode:_textLabel.lineBreakMode forString:_textLabel.text];
_textLabel.frame = CGRectMake(0, _textlabel.frame.origin.y, requiredSize.width, requiredSize.height);
You can set the width to whatever you want your label to fit in. The height would calculated accordingly. But remember to set numberOfLines to 0.
Try to insert following line of code:
_textLabel.numberOfLines = 0;

iOS - Change UILabel font size proportionally

I have several UILables in my view like this:
Those in red colour should never change their font size. Two others in white colour (50 and 50) should decrease their font size proportionally to fit the content.
What I want to achieve is when any of white labels becomes two big the other should start decreasing in size as well:
but instead I get this:
How can I make my UILabels' font size to resize proportionally?
The easiest possible way is as below:
Identify the max possible widths of label 1 and label2.
Sum up widths of both label.
Append both the strings which you want to set in both labels.
Get the font size that fits given (combined) text in combined width.
Now calculate the width of first text for above identified font size and assign it to first label.
Adjust rest of the labels frame according to its frame.
Similarly identify the width of second label.
Assign above derived font size to both labels.
One easy way to do this is by adjusting the fontSize manually using UILabel's sizeToFit method to calculate its bounds.
int fontSize = MAX_FONTSIZE;
BOOL fontSizeNeedsToBeAdjusted = NO;
CGRect originalLabelFrame1 = label1.frame;
CGRect originalLabelFrame2 = label2.frame;
while(fontSizeNeedsToBeAdjusted && fontSize>MIN_FONTSIZE){
label1.frame = originalLabelFrame1;
label1.font = [UIFont systemFontOfSize:fontSize];
[label1 sizeToFit];
label2.frame = originalLabelFrame2;
label2.font = [UIFont systemFontOfSize:fontSize];
[label2 sizeToFit];
if(CGRectGetWidth(label1.frame)>CGRectGetWidth(originalLaeblFrame1) || CGRectGetHeight(label1.frame)>CGRectGetHeight(originalLaeblFrame1))
|| CGRectGetWidth(label2.frame)>CGRectGetWidth(originalLaeblFrame2) || CGRectGetHeight(label2.frame)>CGRectGetHeight(originalLaeblFrame2)){
fontSizeNeedsToBeAdjusted = YES;
fontSize--;
}else
fontSizeNeedsToBeAdjusted = NO;
}
A quicker way would be calculating the size with NSString's boundingRectWithSize: options:attributes:context: method:
NSDictionary *attributes = #{NSFontAttributeName: [UIFont systemFontofSize:fontSize]};
// NSString class method: boundingRectWithSize:options:attributes:context is
// available only on ios7.0 sdk.
CGRect bounds = [label1.text boundingRectWithSize:CGSizeMake(CGRectGetWidth(label1.frame), MAXFLOAT)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:attributes
context:nil];
I expected the answer to this is in NSMutableAttributedString so i did a small experiment with this
NSString *quantity = #"123456";
NSString *metrics =#"m2";
NSString *quantity2 = #"50";
NSString *metrics2 =#"pk";
NSString *separator = #" / ";
NSMutableAttributedString *fullString = [[NSMutableAttributedString alloc] initWithString:
[NSString stringWithFormat:#"%#%#%#%#%#",quantity,metrics,separator,quantity2,metrics2]];
[fullString addAttribute:NSFontAttributeName
value:[UIFont systemFontOfSize:25.0]
range:NSMakeRange(quantity.length+metrics.length, separator.length)];
[fullString addAttribute:NSFontAttributeName
value:[UIFont systemFontOfSize:12.0]
range:NSMakeRange(fullString.length-metrics.length, metrics.length)];
_lblTitle.attributedText = fullString;
So try changing the values and adding attributes you will get what you want

How to obtain adjusted font size from UILabel when adjustsFontSizeToFitWidth is YES in iOS 7?

I have a label that is set to adjustsFontSizeToFitWidth = YES and I need to get the actual displayed font size.
Now iOS 7 deprecated all methods that worked previously and all questions on SO suggest using these deprecated methods.
I will make this question a bounty as soon as I am allowed to by SO. Please do not close.
UILabel displayed fontSize in case of using adjustsFontSizeToFitWidth in iOS 7
UILabel *label=[[UILabel alloc]initWithFrame:CGRectMake(0, 0, 100, 40)];
label.text = #" Your Text goes here into this label";
label.adjustsFontSizeToFitWidth = YES;
NSMutableAttributedString *attrStr = [[NSMutableAttributedString alloc] initWithAttributedString:label.attributedText];
// Get the theoretical font-size
[attrStr setAttributes:#{NSFontAttributeName:label.font} range:NSMakeRange(0, attrStr.length)];
NSStringDrawingContext *context = [NSStringDrawingContext new];
context.minimumScaleFactor = label.minimumScaleFactor;
[attrStr boundingRectWithSize:label.frame.size options:NSStringDrawingUsesLineFragmentOrigin context:context];
CGFloat theoreticalFontSize = label.font.pointSize * context.actualScaleFactor;
NSLog(#"theoreticalFontSize: %f",theoreticalFontSize);
NSLog(#"AttributedString Width: %f", [attrStr size].width);
double scaleFactor=label.frame.size.width/([attrStr size].width);
double displayedFontSize=theoreticalFontSize*scaleFactor;
NSLog(#"Actual displayed Font Size: %f",displayedFontSize);
// Verification of Result
double verification=(displayedFontSize * [attrStr length]);
NSLog(#"Should be equal to %0.5f: %0.5f ", [attrStr size].width/17.0, label.frame.size.width/displayedFontSize);
Try inserting [lblObj sizeToFit] just before requesting the font size
There's a readonly property that lets you do that. You can access it like this
nameLabel.adjustsFontSizeToFitWidth = YES;
//Make sure to use the line below AFTER the line above
float fontSize = nameLabel.font.xHeight;
This will give you the font size after it has been adjusted to fit width.
You can get the font size of UILabel text using these line of code.
UILabel *lblObj = [[UILabel alloc]init];
lblObj.text = #" Your Text";
lblObj.adjustsFontSizeToFitWidth = YES;
float size = lblObj.font.pointSize; //Here You will get the actual size of the text.
float lineHeight = lblObj.font.lineHeight;
Try this one.

UILabel with "+" text not centered vertically

self.iconLabel.frame = self.contentView.frame;
self.iconLabel.font = [UIFont systemFontOfSize:100.0];
self.iconLabel.text = #"+";
self.iconLabel.textColor = [UIColor blackColor];
self.iconLabel.textAlignment = NSTextAlignmentCenter;
So the UILabel's frame is the same size as its container view, self.contentView
I need the "+" to be centered vertically also, I want it in the center.
How can I achieve this?
My only notion is to shift the iconLabel.frame up.
EDIT: Changed from self.iconImageView to self.contentView which is a UIView. The UILabel is layered above the self.iconImageView which is a UIImageView.
EDIT 2: Tried implementing kshitij godara's code, the result is:
I altered the code slightly:
CGSize constraint = CGSizeMake(self.contentView.frame.size.width, self.contentView.frame.size.height);
NSString *str = #"+";
UIFont *myFont = [UIFont systemFontOfSize:100.0];
CGSize stringSize = [str sizeWithFont:myFont constrainedToSize:constraint lineBreakMode:NSLineBreakByWordWrapping];
self.iconLabel.frame = CGRectMake(0, 0, stringSize.width, stringSize.height);
self.iconLabel.font = myFont;
self.iconLabel.lineBreakMode = NSLineBreakByWordWrapping;
self.iconLabel.numberOfLines = 0;
[self.iconLabel sizeToFit];
self.iconLabel.text = str;
EDIT 3:
the frame is quite large:
This is probably a problem of the font itself. Each font has defined it shapes, behavior, typesetting etc. The font seems to be positioning character "+" of the visual vertical center. You can test it on any other string containing letter "+", "dog+Cat" for example. The "+" letter will probably be drawn near bottom as it is on your image.
From my point of view, you have 2 options:
Use icon image instead for the "+" sign. This will be simplest and the best working solution
Use custom font edited to visually look exactly like you need (letter "+" totally centered in its typeset). This one would probably be very painfull and time-consuming option
Edit: Regarding 2nd option: I have already done such an procedure to fix some misaligned fonts following this tutorial. However it still just fixes the whole font, not on a single character basis
You can do this -- Try to apply this
CGSize constraint = CGSizeMake(iconImageFrame.size.width,1000.0f);
//Now Calculate size of string
NSString *str = #"+";
//Always give the same font to calculate size which you giving for label
UIFont *myFont = [UIFont systemFontOfSize:100.0];
CGSize stringSize = [str sizeWithFont:myFont
constrainedToSize:constraint
lineBreakMode:UILineBreakModeWordWrap];
//now set same font for uilabel and also make it to fit to size
//like this
UILabel *myLabel = [[UILabel alloc]initWithFrame:CGRectMake(myIconLabelFrame.x,myIconLabelFrame.y,stringSize.width,stringSize.height)];
myLabel.font = myFont;
myLabel.lineBreakMode = UILineBreakModeWordWrap;
myLabel.numberOfLines = 0;
[myLabelsizeToFit];
myLabel.text = str;
As now label will be completely fit in size , therefore it will always be in center .This code also can be used for to increase height of label dynamically .
I hope it solve your problem .Thanks!

Resources