Dynamic Height of UITableViewCell - iphone

Okay..so before you mark this is as a repeated question, read it. I've implemented the code given by CIMGF for dynamic resizing of UITableViewCell. It worked for the first time around but does not seem to work now. Strange, right?
Anyway, here are the code snippets:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
NSString *text = [[buzzList objectAtIndex:[indexPath row]] objectForKey:#"description"];
CGSize constraint = CGSizeMake(260, 20000.0f);
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
CGFloat height = size.height;
return height +25 +(CELL_CONTENT_MARGIN * 2);
}
and the corresponding code for cellForRowAtIndexPath is:
[cell.descriptionLabel setLineBreakMode:UILineBreakModeWordWrap];
[cell.descriptionLabel setMinimumFontSize:FONT_SIZE];
[cell.descriptionLabel setNumberOfLines:0];
[cell.descriptionLabel setFont:[UIFont systemFontOfSize:FONT_SIZE]];
CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
CGSize size = [[[buzzList objectAtIndex:indexPath.row] objectForKey:#"description"] sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
cell.descriptionLabel.text=[[buzzList objectAtIndex:indexPath.row] objectForKey:#"description"];
CGRect rect=CGRectMake(45, 20, 260, size.height);
[cell.descriptionLabel setFrame:rect];
Where the values 45,20,260 are set by me to get the exact location of starting point of text in the cell and it's width. The values are correct and need no modification. However, When I execute the code, I get the right height for the cell (Dynamically adjustable according to the text) BUT the descriptionLabel shows maximum of 2 lines text. It truncates the text after that. :(

Your constraint for the description label contains two constants CELL_CONTENT_WIDTH and CELL_CONTENT_MARGIN, whereas the CGRect you are creating contains a number (260). If CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2) > 260 then this should be your problem.

Related

How to extend uilabel height as per content?

I want to change the uilabel height as per content and display it in a uitableview cell, there is a custom cell and cell is expand as per uilabel height
When button is pressed then and then cell height is expand as per the uilabel height
Thank you in Advance :-)
//Calculate the size based on the font and linebreak mode of your label
CGSize maxLabelSize = CGSizeMake(300,9999);
CGSize expectedLabelSize = [myString sizeWithFont:myLabel.font
constrainedToSize:maxLabelSize
lineBreakMode:myLabel.lineBreakMode];
//adjust the label the the new height.
CGRect newFrame = myLabel.frame;
newFrame.size.height = expectedLabelSize.height;
myLabel.frame = newFrame;
Try this
[label sizeToFit];
Note that label will increase it's height keeping it's width the same.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *text = displayText;
//CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
CGSize constraint = CGSizeMake(tableView.frame.size.width - 30, 20000.0f);
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:15.0f] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
CGFloat height = MAX(size.height, 44.0f);
return height + 30;
}
Calculate the size of the label text & than set coordinates as
CGSize labelWidth=[_label.text sizeWithFont:[UIFont fontWithName:#"Verdana" size:12] constrainedToSize:CGSizeMake(200, 15) lineBreakMode:UILineBreakModeTailTruncation];

iPhone: Text width in pixels

I have UILabel (286, 50). When I set some text with font Helvetica 16, label divides text on 2 rows. Thats grate. Now I want to get this text width in pixels.
CGSize uiLabelSize = CGSizeMake(286, 50);
return [text sizeWithFont:[UIFont fontWithName:#"Helvetica" size:16]
constrainedToSize:uiLabelSize lineBreakMode:UILineBreakModeWordWrap].width;
But looks like this method dont want to divide this text on 2 rows. it returns for me 284 px.
Any idea how to be ?
return [text sizeWithFont:[UIFont
fontWithName:#"Helvetica" size:16]].width;
This method not work for me. Because if in first row last word is too long, than UILineBreakModeWordWrap will move last word on second row...
Sorry for hard explanation, let me know if I need to be more clear...
Replace 50 with an unconstrained height:
CGSize textSize = [text sizeWithFont:font
constrainedToSize:CGSizeMake(286.0, FLT_MAX)
lineBreakMode:UILineBreakModeWordWrap];
edit:
NSString *text = #"what's wrong with your hair? it's like a science experiment back there. Don't rub more salt in the wound.";
UIFont *font = [UIFont fontWithName:#"Helvetica" size:16];
CGSize textSize = [text sizeWithFont:font
constrainedToSize:CGSizeMake(286.0, FLT_MAX)
lineBreakMode:UILineBreakModeWordWrap];
NSLog(#"%f,%f", textSize.width,textSize.height);
This outputs 272 width (because it is word wrapping before 286 pixels) and 60 height (because it is taking two lines).
UILabel * testLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 286.0f, 50.0f)];
[testLabel setText:#"ab"];
NSLog(#"%f",[testLabel.text sizeWithFont:[UIFont fontWithName:#"Helvetica" size:16] constrainedToSize:CGSizeMake(286.0f, 50.0f) lineBreakMode:UILineBreakModeWordWrap].width);
It looks interesting. So I tried in my xcode and the code above works for me. When set text to #"a", the width returns 9, and #"ab" returns 18.
Have you set the text? Or you may mix the UILabel with its text?
I'm not sure this is that you want, just give some tips.
Try something llike this:
CGSize labelSize = [label.text sizeWithFont:label.font constrainedToSize:label.frame.size lineBreakMode:label.lineBreakMode];
labelSize gets the size of label constrained by text
I'm not sure if it is what you need..

UILabel with -[sizeWithFont:constrainedToSize:lineBreakMode] is cutting off words

UILabel inside of a UITableViewCell. On cell tap, height expands and a second UILabel appears with various amounts of data.
The problem is, if the line wraps, sizeWithFont:constrainedToSize:lineBreakMode: does not return the proper height and cuts off the bottom line.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
labelExpanded = [[[UILabel alloc] initWithFrame:CGRectZero] autorelease];
labelExpanded.font = [UIFont boldSystemFontOfSize:11];
labelExpanded.textAlignment = UITextAlignmentLeft;
labelExpanded.lineBreakMode = UILineBreakModeWordWrap;
labelExpanded.numberOfLines = 0;
[cell.contentView addSubview:labelExpanded];
CGSize constraint = CGSizeMake(300, 20000);
CGSize size = [expandedDetails sizeWithFont:[UIFont boldSystemFontOfSize:11] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
[labelExpanded setText:expandedDetails];
[labelExpanded setFrame:CGRectMake(16, 30, 248, size.height)];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(// Row is Expanded)
{
CGSize constraint = CGSizeMake(300, 20000);
CGSize size = [sameTextAsLabel sizeWithFont:[UIFont boldSystemFontOfSize:11] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
// I found +8 to height added nice padding
CGFloat height = size.height + 8;
}
else // Row is not expanded
return 30;
}
The same text is fed to both, it consists of a string with multiple new lines \n. If the line is longer than width, word wrap does its job but when calculating its dynamic height, it fails to include the wrapped line.
If I add any value to the [labelExpanded setFrame:height] such as [size.height + 30] my wrapped line shows up. However, if the line isn't wrapped, it adds unnecessary whitespace.
I haven't been able to find a solution online for this.
One thing I note is that you are calculating the size based on a width of 300, but sizing the label at 248.
CGSize constraint = CGSizeMake(300, 20000);
CGSize size = [expandedDetails sizeWithFont:[UIFont boldSystemFontOfSize:11] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
[labelExpanded setText:expandedDetails];
[labelExpanded setFrame:CGRectMake(16, 30, 248, size.height)];
Why is the label frame width 248 and constraint width is 300?

heightForRowAtIndexPath for longer NSStrings

I have a UITableView (Grouped!) and need to calculate the height of two styles of cells: UITableViewCellStyleDefault and UITableViewCellStyleValue2.
This is how I do it for UITableViewCellStyleDefault:
CGSize textSize = {300.f, 200000.0f};
CGSize size = [myTextString1 sizeWithFont:[UIFont systemFontOfSize:14.0f] constrainedToSize:textSize lineBreakMode:UILineBreakModeWordWrap];
size.height += 30.0f;
result = MAX(size.height, 44.0f);
And for UITableViewCellStyleValue2:
CGSize textSize = {207.f, 200000.0f};
CGSize size = [myTextString2 sizeWithFont:[UIFont systemFontOfSize:14.0f] constrainedToSize:textSize lineBreakMode:UILineBreakModeWordWrap];
size.height += 30.0f;
result = MAX(size.height, 44.0f);
My issue it that they return incorrect heights and I think it's the textSize where I use incorrect numbers. With long texts, the bottom part gets cut short (usually just a line with a few words), and for both CellStyles they have weird spacing above and below the text in the cell.
For UITableViewCellStyleValue2 I got the width size (207.0f) from making the text.backgroundColor red and then just calculating the size of the box. 300.0f width for UITableViewCellStyleDefault is how big the cell is with UITableViewStyleGrouped.
Does anyone know which values I need to use to properly calculate the size of an NSString and thereby get appropriate height for my cells?
Thanks
Here is the code I am using for this. It works like a charm for one type of cell. It may have some useful parts for your application.
- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath: (NSIndexPath *) indexPath {
AppAppDelegate *appDelegate = (AppAppDelegate *)[[UIApplication sharedApplication] delegate];
NSString *Text = ([[appDelegate.myTextSectionsDelegateDict objectAtIndex:indexPath.section] objectForKey:#"Text"]);
UIFont *cellFont = [UIFont fontWithName:#"Helvetica" size:17.0];
CGSize constraintSize = CGSizeMake(280.0f, MAXFLOAT);
CGSize labelSize = [Text sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];
return labelSize.height + 15;}
When you create your cell, are you using the same font as the one you use to measure?
I used the tutorial on this page and everything worked for me. It might be useful to you too:
It seeems you've figured out that you were using the wrong text size. You might want to just use the font and lineBreakMode properties of the label to avoid this problem in the future, especially if you change them in the cell at a later time. Also, for readability's sake, I would avoid adding to the height before returning a number. Instead I'd try something like this:
CGSize textSize = CGSizeMake( 300.0, 1979 );
CGSize size = [ myTextString1 sizeWithFont:[[ cell textLabel ] font ]
constrainedToSize:textSize
lineBreakMode:[[ cell textLabel ] lineBreakMode ]];
result = MAX( size.height + 30, 44.0f );
I used 1979 because according to the documentation, one should not return values larger than 2009.
If you want to calculate the height properly for cellvalue2 you should use:
[UIFont boldSystemFontOfSize:15.0f] and as linebreakmode: NSLineBreakByTruncatingTail
If you don't use bold, the text will fill correctly but you will lose the correct vertical padding.
The rest of your calculation are correct.
When is working for me is to compute the constraintSize based on the width of the table view:
CGSize constraintSize = CGSizeMake(tableView.frame.size.width * 0.6, 2009);
CGSize labelSize = [cellText sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];
Easiest way to do this:
- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
CGFloat result = 10.0f;
if(indexPath.section == 1) // here i compare the sections
{
result = 400.0f;
}
return result;
}
Return the values based on the sections you have. This will give you custom row heights.

How do I fix a multi-line UILabel that is overflowing its containing UITableViewCell?

I'm having trouble displaying a multi-line UILabel in a custom UITableView cell.
I'm currently using this to calculate both the height of the cell...
NSString *cellText = [howtoSection objectAtIndex:row];
UIFont *cellFont = [UIFont fontWithName:#"Helvetica" size:15.0];
CGSize constraintSize = CGSizeMake(260.0f, MAXFLOAT);
CGSize labelSize = [cellText sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];
return labelSize.height + 20;
...and this is for the label itself.
// Calc the height
NSString *cellText = [howtoSection objectAtIndex:row];
CGSize constraintSize = CGSizeMake(260.0f, MAXFLOAT);
CGSize labelSize = [cellText sizeWithFont:cell.textLabel.font constrainedToSize:constraintSize lineBreakMode:cell.textLabel.lineBreakMode];
// Create the label frame
CGRect newFrame = cell.contentLabel.frame;
newFrame.size.height = labelSize.height;
cell.contentLabel.frame = newFrame;
[cell.contentLabel setText:[howtoSection objectAtIndex:row]];
Everything is working as planned except that the label is being pushed down and out of its cell. If it wasn't for this apparent top margin everything would fit.
Here's a link to a picture of what I'm seeing in the simulator...
iPhone Rendering Bug
Any help here would be greatly appreciated.
I don't see you setting cell.contentLabel.font in the code you show.
Also the label size calculation uses cell.textLabel.font to calculate its size but renders using the contentLabel variable.
Is it possible you're rendering with a different font than the calculation?
How are you adding your label to the contentView? It looks like the original positioning is wrong, since the height looks to be calculated correctly. If you comment out assigning the new frame, is the label in the correct position? My wager is that it isn't.