Size of label changes after being set, depending on string - objective-c

I am facing an issue in getting the correct frame for two different strings. I am running two strings through the below code:
UILabel *myLabel = [[[UILabel alloc] initWithFrame:CGRectZero] autorelease];
myLabel.lineBreakMode = UILineBreakModeWordWrap;
myLabel.numberOfLines = 2;
myLabel.textAlignment = UITextAlignmentCenter;
myLabel.font = [UIFont boldSystemFontOfSize:11];
myLabel.text = #"About Stores"
myLabel.text = #"About Rivers"
CGSize myLabelSize = CGSizeMake(70,28);
[myLabel sizeWithFont:myString.font // <-- One of two strings
constrainedToSize:aLabelSize
lineBreakMode:UILineBreakModeWordWrap];
Result for myString1 => Width: 70, Height: 28
Result for myString2 => Width: 70, Height: 14
Why there is a difference here?

Issues I see:
1
NSString has no font property. You might want to replace "myString.font" with UILabel.font where the UILabel is to be replaced by the instance of UILabel you plan to use to display the string.
2
sizeWithFont is supposed to return a CGSize that you store in an instance of CGSize.
Seems like you're not very clear on using this. I've posted an answer on how to correctly use sizeWithFont. You should check that out here : Place two UILabels side by side left and right without knowing string length of text in left label
By the way, that's why you see a difference in the heights... I think a garbage value is being passed in as the font size argument. If you hardcode the font size argument, you'll see consistent results.

just replace the code n give a try.....i don kno if it works jus check :)
[myLabel sizeWithFont:[UIFont fontWithName:#"Helvetica-Bold" size:11]
constrainedToSize:myLabelSize lineBreakMode:UILineBreakModeWordWrap];
and also ";" is missing in label`
myLabel.text = #"About Stores";
myLabel.text = #"About Rivers";`
regards..

There's a difference because the system font is Helvetica, which is a variable-sized font. The text in myString1 is maginally wider than the text in myString2, so the string needs to wrap to a second line in order to fit. Since you specified 2 lines max and UILineBreakModeWordWrap, that's what you get. If you want it to fit in one line, make myLabelSize a little wider or else use a smaller font size.

Related

Calculating the exact size of a CGRect frame for a pdf based on UITextField

I am creating a pdf report that renders frames based on text in a series of UITextFields. Currently I am using a series of methods as below. The variables are used to keep track of the position for the next frame and are based on the length of the text in the current UITextField being considered and the assumption that when rendered the length of each line is around 97 characters on the pdf doc.
-(void) drawTextObservationComment;
{
//pdfLineHeight is the height of size 12 rendered text
pdfLineHeight = 15;
CGContextRef summaryContext = UIGraphicsGetCurrentContext();
UIFont *font = [UIFont fontWithName:#"arial" size:12];
CGContextSetFillColorWithColor (summaryContext, [UIColor blackColor].CGColor);
//pdfCurrentLine is the y-axis coordinate from which to begin the new frame
CGRect textRect = CGRectMake(60, pdfCurrentLine, 650, 300);
NSString *myString = self.observationComment.text;
[myString drawInRect:textRect withFont:font lineBreakMode:NSLineBreakByWordWrapping alignment:NSTextAlignmentLeft];
//checks for the no of carriage returns within the text field
NSInteger numberOfLines = [[myString componentsSeparatedByString:#"\n"] count];
//the new pdfCurrentLine value is the previous value
// + the no of new lines based on text length
// + the no lines based on the no of carriage returns within text field
// + 40 as standard gap
pdfCurrentLine = pdfCurrentLine + (([observationComment.text length]/97)*pdfLineHeight) + ((numberOfLines - 1) * pdfLineWidth) + 40;
}
This works to a certain extent, but I realise that it is not perfectly accurate. The rendered text in the CGRect frame is often not 97 characters (although it is usually around this figure give or take 10 chars). This depends on the text entered (the letter 'i' being thinner for example and therefore there may be more chars on a line where there are a lot of 'i's).
I would like to know if there is any way of accurately calculating exactly how many lines the rendered text will actually use, therefore allowing me to accurately calculate the exact position of the next frame. Or any other advice gratefully received.
Have you looked at the Documentation for NSString UIKit Additions?
There are methods in there that return the size of rendered text such as sizeWithFont:constrainedToSize and sizeWithFont:constrainedToSize:lineBreakMode:.

UILabel truncate text not working

I set the numberOfLines to 1 in the IB, but when I set the text to a long string, it doesn't truncate. If I set the numberOfLines to 2, the truncate works fine.What should I do to truncate a long string into a single line?
simple, set the following properties:
label.adjustsFontSizeToFitWidth = NO;
label.lineBreakMode = NSLineBreakByTruncatingTail;
If you're using attributed string and having set paragraph style to the attributed string: make sure you're passing paragraphStyle.lineBreakMode = .byTruncatingTail.
If using auto layout, in my case, there was a constraint missing. The UILabel grows its width if no constraint is set on its width/trailing. Once its width is limited, for instance to its superview, the truncation occurs.
You probably have a constraint on a label in that section that is making things go haywire.
Double check your constraints or remove them for that label or other controls in that section.
The storyboard option for a label: "Line Breaks:Truncate Tail" will to the work you are looking for.
If you set the label's autoshrink to "Fixed Font Size" in IB, you will always get a truncatation when the string width beyond the label width. I guess you happened to set that to "Minimum Font Scale" or "Minimum Font Font", which will lead a resizing when the string is too long.
(Xcode 4.5, other version of Xcode and IB may be different property name)
I make two functions, that will help you to do your work.
Basic:
This solution I made for task:
"minimize font to my min size of font and then put as much info, as possible, but not bigger then maximum width"
takeFineFont... function parameters:
(UIFont*)font - font of the your label (titleLabel.font)
(NSString*)string - text in your label (titleLabel.text)
(CGSize)limitStringSize - limit size.
limitStringSize.width - width limit of your label (Upper limit)
limitStringSize.height - height limit of your label (Lower limit)(actually, size of font)
-(UIFont*)takeFineFontSize:(UIFont*)font
forText:(NSString*)string
andLimit:(CGSize)limitStringSize{
UIFont* resultFont = [UIFont fontWithName:[font fontName] size:[font pointSize]];
if(limitStringSize.width != 0 && limitStringSize.height != 0){
CGSize currentSize = [string sizeWithFont:resultFont];
while(/* change font width with upper bound */
currentSize.width > limitStringSize.width
&&
/* change font height with lower bound */
currentSize.height > limitStringSize.height){
/*change height and take new width*/
currentSize.height -= 1;
currentSize.width = [string sizeWithFont:[resultFont fontWithSize:currentSize.height]].width;
}
resultFont = [resultFont fontWithSize:currentSize.height];
}
return resultFont;
}
-(double)takeFineWidthForFont:(UIFont*)font
forString:(NSString*)string
andLimit:(double)widthLimit{
return MIN([string sizeWithFont:font].width, widthLimit);
}
Suppose, that you have big string in UILabel* titleLabel
And you define somewhere:
#define maximumLengthOfYourLabel 300
#define minimumSizeOfFont 14
what you will do now? just do this peace of code:
-(void)updateTitleLabelWithBigText:(NSString*)string{
/*change text*/
self.titleLabel.text = string;
/*take pretty small font*/
self.titleLabel.font = [self takeFineFontSize:self.titleLabel.font
forText:self.titleLabel.text
andLimit:CGSizeMake(maximumLengthOfYourLabel,minimumSizeOfFont)
];
/*if your text still big, take minimal width and trunctate it*/
self.titleLabel.width = [self takeFineWidthForFont:self.titleLabel.font
forString:self.titleLabel.text
andLimit:maximumLengthOfYourLabel];
self.titleLabel.lineBreakMode = NSLineBreakByTruncatingTail;
}
Ensure you are not calling sizeToFit() on your label. It will override the label and constraint settings.
set numberOfLines to 0, this will let you expand uilabel content vertially without truncating its width.
Perhaps this method can help you:
[myLabel sizeToFit];
The label won't be truncated but it will adjust the label size to fit in one line.

Render UILabel in multiple line in iOS5?

I'm trying to render my UILabel in multiple line.
i've tried:
CGRect rect2 = CGRectMake(100, 45, 150, 60);
FontLabel *addresLbl1 = [[FontLabel alloc] initWithFrame:rect2
fontName:#"arial" pointSize:12.0f];
//#006000
addresLbl1.textColor = [UIColor colorWithRed:84/255.0 green:84/255.0 blue:84/255.0 alpha:1.0];
addresLbl1.text = #"401 King St\\nToronto, Ontario, M5V1K1\\nCanada";
//[addresLbl1 setTextAlignment:UITextAlignmentCenter];
addresLbl1.backgroundColor = nil;
addresLbl1.opaque = NO;
[cell.contentView addSubview:addresLbl1];
[addresLbl1 release];
but it is rendered as 401 King St\nToronto, Ontario, M5V1K1\nCanada
Note that this label is added on cell of UITableView.
I need new line from the position of '\n' in string and this string will come from server, so position of '\n'may vary
You shouldn't use doubble backslashes.
\\ is the code used for \, so \\n will be parsed and printed as \n
So you're code should be like this:
addresLbl1.text = #"401 King St\nToronto, Ontario, M5V1K1\nCanada";
addresLbl1.numberOfLines = 0;
By default UILabel sets its property numberoflines to 1, which means your text will be rendered in one line. Try to set that property to 0, as indicated by the documentation
This property controls the maximum number of lines to use in order to
fit the label’s text into its bounding rectangle. The default value
for this property is 1. To remove any maximum limit, and use as many
lines as needed, set the value of this property to 0.
If you constrain your text using this property, any text that does not
fit within the maximum number of lines and inside the bounding
rectangle of the label is truncated using the appropriate line break
mode.
When the receiver is resized using the sizeToFit method, resizing
takes into account the value stored in this property. For example, if
this property is set to 3, the sizeToFit method resizes the receiver
so that it is big enough to display three lines of text.
you need to first set numberOfLines to 0, and then
unichar chr[1] = {'\n'};
NSString *singleCR = [NSString stringWithCharacters:(const unichar *)chr length:1];
[yourLabel setText:[NSString stringWithFormat:#"new%#line",singleCR]];
this will ensure what you wanted.
For multiple lines you can use UILabel property numberOfLines as
label.numberOfLines = 3;
In your case your text can fit only in one line so if you want it in multiple lines better you should define 3 different labels.

How to make a NSString always use fixed font width

I want to have an NSString in the format "hh:mm:ss" to use exactly the same amount of pixel space as the string "88:88:88". Is that possible?
Now I'm using:
// ...
NSMutableString * strS = [[NSMutableString alloc] initWithFormat:#"%d", Seconds];
if (Seconds<10){
[strS insertString:#"0" atIndex:0];
}
// Make the time to show
[ClocklLabel setText:[NSString stringWithFormat:#"%2#:%2#:%2#", strH,strM,strS]];
with no success!
I think you're looking for a monospaced font. Try using Courier for example:
UIFont *courier = [UIFont fontWithName:#"Courier" size:12.0f];
label.font = courier;
If you're trying to create a digital clock display, you could also simply use a separate label for each number and position the labels however you want.
You could use a monospace font. If you do not want this, use a UILabel and set adjustsFontSizeToFitWidth to YES. However, in this case the height will vary.
The title of your question hints to the fact that you are missing an important detail. NSString only contains the actual text.
It is not the NSString that dictates font, color or other attributes. As other answers have suggested you should set the font to the label/textfield/button or whatever visual gadget is supposed to display the string.
If you want to combine both text and text attributes, you may want to check NSAttributedString.

Is there a way to obtain the length of the cell's subtitle (detailedTextLabel)?

as mentioned in the question, I would like to obtain the length of the subtitle (topic.context) and use it to make certain decisions (see my code snippet below)
cell.detailTextLabel.text = topic.context;
NSString *fanLabelText = [NSString stringWithFormat:#"%i fans",topic.num_fans];
if (topic.context && ![topic.context isEqual:[NSNull null]] && topic.context.length > 46)
{
thisFanLabel.frame = CGRectMake(320 - 150, -10, 100, 44);
}
else
{
thisFanLabel.frame = CGRectMake(320 - 150, 0, 100, 44);
}
Basically, I want to know when the subtitle will reach a certain length so that I can adjust the fan label to be shifted upwards (as seen in the diagram below). Currently the fans label is being overlapped by the subtitle, I want to be able to shift the label upwards when this happens.
So what would be the best way to obtain the accurate length of the subtitle?
You can check the size of a string with a certain font by using the following lines:
CGSize maxSize = CGSizeMake(9999,9999);
UILabel *myLabel = cell.detailTextLabel;
CGSize sizeOfString = [myLabel.text sizeWithFont:myLabel.font
constrainedToSize:maxSize
lineBreakMode:myLabel.lineBreakMode];
In "sizeOfString" you should now have the size of your detailLabel.
See NSString's -sizeWithFont: and related methods.