TableView Cell Auto Height - ios

I have a TextView in the UITableViewCell, and I want my height TableViewCell is auto according TextView height.
I had worked some code, but it display on the IOS 8 only, I want it can action on the IOS 7.
Please help me!
Thanks all.
Here is image my code, it work on the IOS 8 very good.
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *messageText = [NSString stringWithFormat:#"%#", [DicMessagesData objectForKey:#"ContentMessage"]];
CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
CGRect textRect = [messageText boundingRectWithSize:constraint options:NSStringDrawingUsesLineFragmentOrigin attributes:#{NSParagraphStyleAttributeName: paragraphStyle.copy} context:nil];
return textRect.size.height + 30;
}

the best method i have found :
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *text = #"your text";
CGSize maximumLabelSize = CGSizeMake(CELL_CONTENT_WIDTH, 9999);
UILabel *notesLabel = [[UILabel alloc] init];
notesLabel.font = [UIFont systemFontOfSize:18];
notesLabel.text = text;
notesLabel.numberOfLines = 0;
notesLabel.lineBreakMode = NSLineBreakByWordWrapping;
CGSize expectSize = [notesLabel sizeThatFits:maximumLabelSize];
return expectSize.height + 40;
}

you can use this code:
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *text = #"your text";
CGSize maximumLabelSize = CGSizeMake(CELL_CONTENT_WIDTH, 9999);
UITextField *textField = [[UITextField alloc] init];
textField.font = [UIFont systemFontOfSize:18];
textField.text = text;
CGSize expectSize = [textField sizeThatFits:maximumTXTSize];
return expectSize.height + 40;
}

A few months ago I faced the same problem. Thankfully I found a simple blog on Table View Cells With Varying Row Heights. It will solve your problem.

Try this. It works. This will give dynamic height for each tableview cell based on the content.
- (CGFloat)heightForText:(NSString *)bodyText
{
NSAttributedString *attrStr = [[NSAttributedString alloc] initWithString:bodyText];
CGFloat width = 278;
CGRect rect = [attrStr boundingRectWithSize:CGSizeMake(width, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading context:nil];
return rect.size.height+10;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
lblComment.numberOfLines = 0;
lblComment.lineBreakMode = NSLineBreakByWordWrapping;
CGFloat rowHeight = [self heightForText:[[allCommentsArr objectAtIndex:indexPath.row]objectForKey:#"comment"]];
lblComment.frame = CGRectMake(25, 25, 278, rowHeight);
NSLog(#"rowHeight=%f", rowHeight);
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat rowHgt=[self heightForText:[[allCommentsArr objectAtIndex:indexPath.row]objectForKey:#"comment"]];
NSLog(#"rowHgt=%f", rowHgt);
return rowHgt+25;
}

Related

Resizing UILabel inside UITableViewCell to fit content

I have successfully resized my UITableViewCell to fit it's content, but my UILabel is not resizing properly. This is how I'm resizing the cell:
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *str = #"My really long text";
CGSize constrainedSize = CGSizeMake(250, 9999);
NSDictionary *attributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
[UIFont fontWithName:#"HelveticaNeue-Light" size:16.0], NSFontAttributeName,
nil];
NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:str attributes:attributesDictionary];
CGRect requiredHeight = [string boundingRectWithSize:constrainedSize options:NSStringDrawingUsesLineFragmentOrigin context:nil];
if (requiredHeight.size.width > 250) {
requiredHeight = CGRectMake(0,0, 250, requiredHeight.size.height);
}
if (requiredHeight.size.height + 10 >= 60)
return requiredHeight.size.height + 10;
else
return 60;
}
I create my UILabel in my prototype cell in Storyboard
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Post-Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
UILabel *text = (UILabel *)[cell viewWithTag:2];
text.text = #"My Label's Text";
[text sizeToFit];
return cell;
}
I use this for my dynamic labels. First I know my label is constrained over 60px from the left and 67 from the right. So I know my label will have the screen width minus that padding to fit its content before wrapping. This method will give me the height of the title no matter how many lines. I set a lowest height to 44 so that even if the user has uber small text I still have a nice sized cell. The label in my cell is 11 px from the top and 11 from the bottom of the content view so I add 22 to the height for padding.
+ (CGFloat)cellHeightForTitle:(NSString*)title
{
UIFont *font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
NSString *text = title ?: #"test";
CGFloat hotizontalPadding = 127;
CGFloat desiredWidth = [UIScreen mainScreen].bounds.size.width - hotizontalPadding;
NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:text attributes:#{NSFontAttributeName: font}];
UILabel *label = [[UILabel alloc] init];
label.attributedText = attributedText;
label.numberOfLines = 0;
label.lineBreakMode = NSLineBreakByWordWrapping;
CGSize size = [label sizeThatFits:CGSizeMake(desiredWidth, CGFLOAT_MAX)];
font = nil;
attributedText = nil;
return MAX(44, size.height + 22);//top + bottom padding
}
Then in my table I call
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return [MyCell cellHeightForTitle:#"Some long title"];
}

Height issues with UILabel in UITableViewCell

I'm experiencing some trouble with a UILabel in a UITableViewCell that extend its height nicely. But when the cell is reused, and the UILabel text changes, scrolling back up passed labels with correct height when I scrolled down, now is wrong.
As far as I can understand, this is an issue with the UILabel height, but I don't understand what and why it happens.
Heres a video of it happening:
You can see how the labels in the table cells below the images is looking good, but when I scroll back up, they are suddenly only two lines, instead of four.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
InstagramMedia *media = mediaArray[indexPath.section];
CGSize maximumLabelSize = CGSizeMake(304.0f, 20000.0f);
CGSize expectedLabelSize = [media.caption.text sizeWithFont:[UIFont systemFontOfSize:13.0f] constrainedToSize:maximumLabelSize lineBreakMode:NSLineBreakByWordWrapping];
return (320.0f + expectedLabelSize.height + 20.0f);
}
Am I missing something here?
I have tried using slightly different approach and it worked in the simulator. Cells kept their height on scrolling.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
InstagramMedia *media = mediaArray[indexPath.section];
NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:[UIFont fontWithName:#"HelveticaNeue" size:12], NSFonatAttributeName, nil];
NSAttributedString *textStr = [[NSAttrebutedString alloc]initWithString:media.caption.text attributes:attributes];
CGSize maximumLabelSize = CGSizeMake(304.0f, 20000.0f);
CGRect expLblRect = [textStr boundingRectWithSize:maximumLabelSize options:NSStringDrawingUsesLineFragmentOrigin context:nil];
return (320.0f + expLblFrame.size.height + 20.0f);
}
Try this :
- (CGFloat)tableView:(UITableView *)_tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
UILabel *lbl = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 186, 0)]; //max width that is allowed for label
lbl.numberOfLines = 0;
lbl.lineBreakMode = NSLineBreakByWordWrapping;
int GAP = 3;
float height = 0;
float fontSize = 14;
NSString *cellText = yourtext;
lbl.font= [ UIFont fontWithName:FONT_NAME_Ubuntu size: fontSize];
bl.text = cellText;
[lbl sizeToFit];
height += lbl.frame.size.height;
height += GAP;
return height;
}
Or you can try this :
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
/*
for dynamic cell heigh according to the description display in cell
*/
NSDictionary *dict1 = (NSDictionary*)[array objectAtIndex:indexPath.row];
NSString *cellText = [dict1 valueForKey:#"test"];
UIFont *cellFont = [UIFont fontWithName:FONT_NAME_GOTHAM_4 size:11.0];
CGSize constraintSize = CGSizeMake(280.0f, MAXFLOAT);
CGSize labelSize = [cellText sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:NSLineBreakByWordWrapping];
return labelSize.height + 80;
}

UILabel doesn't change height in UITableViewCell in first scroll

I'm using tableview on storyboard.
I change label's frame in (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath function.
then, after some scrolling, it can change frame. but, when I open my application, frame doesn't change at first.
sorry, can't post image till 10 reputation.
please help.
- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
// get one row
Plan* planObj = [_planObjList objectAtIndex:indexPath.row];
// get custom cell info
LargeImageCell* cell = (LargeImageCell*)[tableView dequeueReusableCellWithIdentifier:#"CustomLargeImageCell"];
cell.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"bg"]];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.titleLabel.text = planObj.planTitle;
cell.titleLabel.numberOfLines = 0;
cell.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
cell.userNameLabel.text = planObj.getProducerName;
// title size
CGSize titleSize = [cell.titleLabel.text boundingRectWithSize:CGSizeMake(300.0f, CGFLOAT_MAX) options:(NSStringDrawingUsesLineFragmentOrigin) attributes:#{NSFontAttributeName: cell.titleLabel.font} context:nil].size;
// user name size
CGSize userNameSize = [cell.userNameLabel.text boundingRectWithSize:CGSizeMake(300.0f, CGFLOAT_MAX) options:(NSStringDrawingUsesLineFragmentOrigin) attributes:#{NSFontAttributeName: cell.userNameLabel.font} context:nil].size;
// set title size
cell.titleLabel.frame = CGRectMake(7.0f, 230.0f, 306.0f, ceilf(5.0f + titleSize.height));
cell.titleLabel.backgroundColor = [UIColor redColor];
// set name size
cell.userNameLabel.frame = CGRectMake(7.0f, ceilf(235.0f + titleSize.height), 148.0f, ceilf(5.0f + userNameSize.height));
cell.userNameLabel.backgroundColor = [UIColor blueColor];
}
autolayout was problem.
I switched off 'Use Autolayout' on storyboard. then, it became clear.
thank you all.
If your app is using Autolayout you should do it with Constraints. To resize a UILabel with Constraints that should has at least that properties:
Line Numbers = 0
Line Breaks = Word Wrap
And about Constraints you should set in both sides, and one to top, DONT set to bottom!!
To set right size in the row u can use this code example:
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
id data = [self.listOfNews safeObjectAtIndex:indexPath.row];
UIFont *font = [UIFont fontWithName:K_FONT_AVENIR_MEDIUM size:textSize];
if ([data isKindOfClass:[NewsModel class]]) {
NewsModel *news = (NewsModel *)data;
if (SYSTEM_VERSION_LESS_THAN(#"7.0")) {
CGSize constraintSize = CGSizeMake(cellTextWidth, MAXFLOAT);
CGSize textRect = [news.title sizeWithFont:font constrainedToSize:constraintSize];
return textRect.height + paddingTopAndBottom;
} else {
CGRect textRect = [news.title boundingRectWithSize:CGSizeMake(cellTextWidth, CGFLOAT_MAX)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:#{NSFontAttributeName:font}
context:nil];
return textRect.size.height + paddingTopAndBottom;
}
}
return 0;
}
Try resizing frames in willDisplayCell delegate method.
You can't change the size initially through cellForRow method. You need to calculate the size and return it in the following delegate
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
To calculate size for a label based on the text use
NSString *labelText=#"some text";
[myLabel setText:labelText];
UIFont *labelTextFont = [UIFont fontWithName:#"Helvetica" size:labelTextsize];
CGSize labelFrameSize = [labelText sizeWithFont:labelTextFont];
myLabel.frame = CGRectMake(xPos, yPos, labelFrameSize.width, labelFrameSize.height);
Remember these steps in order to have UILabel to change size:
1) If you have a Custom UITableViewCell, switch off AutoLayout on elements of the cell
2) Use heightForRowAtIndex protocol method to change the height
3) Set the numberOfLines = 0 for the UILabel inside the cell
4) If this does not work re-set the frame ( I found that this happens when you are trying to enlarge a UILabel in some "far" end of the cell)
Examples
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
GeneralCell* cell = [tableView dequeueReusableCellWithIdentifier:#"GeneralCell"];
if (cell == nil) {
cell = [[GeneralCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"GeneralCell"];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
/////// USE the following block if still in trouble
CGRect frame = cell.label.frame;
[cell.label setFrame:frame];
[cell.label sizeToFit]; // this should not be necessary in general
///////////
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *detail = [NSString stringWithFormat:#"YOUR TEXT]];
CGSize constraintSize = CGSizeMake(CELL_CONTENT_WIDTH, MAXFLOAT);
CGSize labelSize = [detail boundingRectWithSize:constraintSize
options:NSStringDrawingUsesLineFragmentOrigin
attributes:#{NSFontAttributeName:[UIFont systemFontOfSize:FONT_SIZE]}
context:nil].size;
float h = (fmod((int)labelSize.height ,2) == 0) ? labelSize.height : labelSize.height+1;
CGFloat height = MAX(h, 30.0f);
elemento = nil;
detail = nil;
return height + (CELL_CONTENT_MARGIN * 2);
}

height For Row At Index Path not correct display

a boy of StackOverflow had given such help to set the height of the cells automatically based on the content of the label ...
I have implemented his method but when I scroll on tavleview, all the text in each cell overlaps and do not read anything ... Can you tell me what 's wrong with this code?
I had to change CGSize because I'm working on some code ios7 was deprecated for example:
 
CGSize size = [comment sizeWithFont: [UIFont systemFontOfSize: 14] constrainedToSize: lineBreakMode constraint: UILineBreakModeWordWrap];
Can you help me please?
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
PFObject *object = [self objectAtIndexPath:indexPath];
//Here you are getting the comment again. This is necessary to determine how tall you need
//the cell to be
NSString *comment = [object objectForKey:(#"Testo")];
// Again you are getting the constraints because you are going to us this size
// to constrain the height of the cell just like you determined the size for the label.
CGSize constraint = CGSizeMake(250 - (10 * 2), 10000.0f);
// Again, determining the size that we will need for the label, because it will drive
// the height of the cell
UIFont *FONT = [UIFont systemFontOfSize:11];
CGSize size = [comment boundingRectWithSize:constraint options:NSStringDrawingUsesLineFragmentOrigin attributes:#{NSFontAttributeName:FONT }context:nil].size;
// Finally, we can determine the height for the cell!
CGFloat height = MAX(size.height, 44.0f);
// return the height, which is the height of the label plus some extra space to make
// it look good.
return height + (10 * 2);
}
// Override to customize the look of a cell representing an object. The default is to display
// a UITableViewCellStyleDefault style cell with the label being the first key in the object.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
NSString *text = [object objectForKey:#"Testo"];
CGSize constraint = CGSizeMake(250 - (10 * 2), 10000.0f);
// This is determining the size that you will need for the label based on the comment
// length and the contraint size
UIFont *FONT = [UIFont systemFontOfSize:11];
CGSize size = [text boundingRectWithSize:constraint options:NSStringDrawingUsesLineFragmentOrigin attributes:#{NSFontAttributeName:FONT }context:nil].size;
// Here you are creating your label and initializing it with the frame that you have
// determined by your size calculations above
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 300, MAX(size.height, 44.0f) + 20.0f)];
// setting up the label properties
label.numberOfLines = 0;
label.lineBreakMode = NSLineBreakByWordWrapping;
label.text = text;
label.font = [UIFont systemFontOfSize:11];
// adding the label view to the cell that you have created
[cell.contentView addSubview:label];
// Configure the cell
return cell;
}
Solved
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
NSString *comment = [[self.objects objectAtIndex:[indexPath row]] objectForKey:#"Testo"];
CGFloat whidt = 260;
UIFont *FONT = [UIFont systemFontOfSize:15];
NSAttributedString *attributedText =[[NSAttributedString alloc] initWithString:comment attributes:# { NSFontAttributeName: FONT }];
CGRect rect = [attributedText boundingRectWithSize:(CGSize){whidt, MAXFLOAT}
options:NSStringDrawingUsesLineFragmentOrigin
context:nil];
CGSize size = rect.size;
return size.height +130;
}
- (FFCustomCellTimeline *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object {
FFCustomCellTimeline *cell = (FFCustomCellTimeline * )[self.tableView dequeueReusableCellWithIdentifier:#"Cell"];
if (!cell) {
cell = [[FFCustomCellTimeline alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
}
NSString *text = [object objectForKey:#"Testo"];
CGSize constraint = CGSizeMake(260 , 20000.0f);
UIFont *FONT = [UIFont systemFontOfSize:15];
CGSize size = [text boundingRectWithSize:constraint options:NSStringDrawingUsesLineFragmentOrigin attributes:#{NSFontAttributeName:FONT }context:nil].size;
return cell;
}

How to set height of UILabel to contain an NSString with variable length, in a UITableView

I need to create a UITableView in which UITableViewCell contains two UILabel, one of them should fit height to its content NSString. The width of the UILabel is fixed, and the number of lines is set to 0. How can I get the height ?
I see code like this:
CGSize maximumSize = CGSizeMake(300, 9999);
NSString *myString = #"This is a long string which wraps";
UIFont *myFont = [UIFont fontWithName:#"Helvetica" size:14];
CGSize myStringSize = [myString sizeWithFont:myFont
constrainedToSize:maximumSize
lineBreakMode:self.myLabel.lineBreakMode];
but the result is: there is only one character in a line of UILabel.
Why cannot I use this method? Thank you very much!
Try this
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *str = #"This is a very very long string which wraps";
CGSize size = [str sizeWithFont:[UIFont fontWithName:#"Helvetica" size:17] constrainedToSize:CGSizeMake(280, 999) lineBreakMode:UILineBreakModeWordWrap];
return size.height + 10;
}
I finally get it working, code in my project:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"shopmessage";
UITableViewCell *cell;
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
UILabel* content = (UILabel*)[cell viewWithTag:11];
UILabel* date = (UILabel*)[cell viewWithTag:12];
NSDictionary* msg = [ _msglist objectAtIndex:indexPath.row];
NSString* type = [[msg objectForKey:#"msgtype"] intValue] == 0 ? #"我:":#"店家:";
[content setText:[NSString stringWithFormat:#"%#%#",type,[msg objectForKey:#"sendmsg"]]];
[date setText:[msg objectForKey:#"sendtime"]];
CGSize contentsize = [content.text sizeWithFont:[UIFont systemFontOfSize:17] constrainedToSize:CGSizeMake(280, 1000) lineBreakMode:UILineBreakModeWordWrap];
// content.frame.size = contentsize;
content.frame = CGRectMake(content.frame.origin.x, content.frame.origin.y, contentsize.width, contentsize.height);
[date setText:[msg objectForKey:#"sendtime"]];
// date.frame.origin = CGPointMake(date.frame.origin.x, content.frame.origin.y + content.frame.size.height + 10);
date.frame = CGRectMake(date.frame.origin.x, content.frame.origin.y + content.frame.size.height, date.frame.size.width, date.frame.size.height);
return cell;
}
- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary* msg = [ _msglist objectAtIndex:indexPath.row];
NSString* text =[msg objectForKey:#"sendmsg"];
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:17] constrainedToSize:CGSizeMake(280, 1000) lineBreakMode:UILineBreakModeCharacterWrap];
return size.height + 30;
}
reference:Apple Support Communities

Resources