Customized UITableViewCell Update Subviews - ios

I have a customized a UITableviewCell. There is a title label and a detail label inside.
Now I want to adjust the detail label attributes according to the content.
If the string size is greater than the frame then set the number of line to 2.
I have tried to put the code in the cellForRowAtIndexPath or layoutSubViews in the cell class.
The piece of code is like
TransportationViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
UIFont* font = cell.detailLabel.font;
NSDictionary* attribute = #{NSFontAttributeName:font};
const CGSize textSize = [cell.detailLabel.text sizeWithAttributes: attribute];
if (textSize.width > cell.detailTextLabel.frame.size.width && cell.detailLabel.numberOfLines == 1) {
NSLog(#"%lf, %lf, %lu", cell.detailLabel.frame.size.width, textSize.width, (long)cell.detailLabel.numberOfLines);
cell.detailTextLabel.font = [UIFont systemFontOfSize:8];
cell.detailTextLabel.numberOfLines = 2;
[cell setNeedsLayout];
}
It actually passed the if condition but the setting of label doesn't work.

write below code in view didload
self.theTableView.estimatedRowHeight = 100;
self.theTableView.rowHeight = UITableViewAutomaticDimension;
[self.theTableView setNeedsLayout];
[self.theTableView layoutIfNeeded];
In cellForRowAtIndexpath cell.detailTextLabel.numberOfLines = 0;

set numberOfLines = 0;
this will solve your problem.
Edit 1: code for calculating dynamic height.
CGSize boundingBox = [label.text boundingRectWithSize:constraint
options:NSStringDrawingUsesLineFragmentOrigin
attributes:#{NSFontAttributeName:label.font}
context:context].size;
Thne on the basis of this height you can do the further calculations.
For more info, you can check this answer https://stackoverflow.com/a/27374760/5660422

Related

How to change the height of a custom cell individually within a UITableView?

I am trying to change the height of each cell individually based on how long my UILabel is, but it does not seem to change.
I have found the following question: How to change cell height dynamically in UITableView static cell
I tried the solution from that question:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
//return 110;
NewsFlashCustomCell *cell;
static NSString *CellIdentifier = #"CustomCell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
[cell layoutIfNeeded];
return cell.messageLabel.frame.origin.y + cell.messageLabel.frame.size.height;
}
However, that seems to do nothing.
Here's a screenshot:
I'd like the height of the cells containing "tidal wave" and "mashup" to be smaller than the last 2 cells since it has a longer message.
I cannot perform a indexPath.row check to change each cell individually because each message is pulled from a database, so the length of the message varies.
What can be done?
In case it helps, here's a screenshot of my constraints:
Thanks.
UPDATE:
I added the following code in viewDidLoad:
tableView.rowHeight = UITableViewAutomaticDimension;
This is what it looks like:
If you can't set try with other method reduce the label font size depend upon the cell height .
label.numberOfLines=0;
label.clipsToBounds=YES;
label.adjustsFontSizeToFitWidth=YES;
label.lineBreakMode = NSLineBreakByWordWrapping;
You can calculate height for label from its length of text and do it like following way:
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return [self calculateHeightForCellAtIndexPath:indexPath];
}
#pragma mark - cell height handling
-(CGFloat)calculateHeightForCellAtIndexPath:(NSIndexPath *)indexP{
UILabel *lbl = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, self.tableView.frame.size.width-22, defaultHeightOfYourLabel)];
NSString *strLbl;
strLbl = [yourArray objectAtIndex:indexP.row];
lbl.text = strLbl;
if (IS_IPAD) {
[lbl setFont:fontRegular15];
}else{
[lbl setFont:fontRegular12];
}
UIFontDescriptor * fontDLBLTime = [lbl.font.fontDescriptor
fontDescriptorWithSymbolicTraits:UIFontDescriptorTraitBold];
if (IS_IPAD) {
[lbl setFont:[UIFont fontWithDescriptor:fontDLBLTime size:15]];
}else{
[lbl setFont:[UIFont fontWithDescriptor:fontDLBLTime size:12]];
}
[lbl setLineBreakMode:NSLineBreakByClipping];
[lbl setNumberOfLines:0];
int noOfLines = [GlobalFunction lineCountForLabel:lbl];
CGFloat height = [GlobalFunction heightForWidth:lbl.frame.size.width usingFont:lbl.font forLabel:lbl];
if (noOfLines>1) {
return height + 33; //here 33 is sum of top and bottom space from view.
}
return 50; //default height of cell.
}
In your class implement following methods:
#define CGFLOAT_MAX_HEIGHT 2000.0
+ (int)lineCountForLabel:(UILabel *)label {
return ceil([self heightForWidth:label.frame.size.width usingFont:label.font forLabel:label] / label.font.lineHeight);
}
+(CGFloat)heightForWidth:(CGFloat)width usingFont:(UIFont *)font forLabel:(UILabel *)lbl{
NSStringDrawingContext *context = [[NSStringDrawingContext alloc] init];
CGSize labelSize = (CGSize){width, CGFLOAT_MAX_HEIGHT};
CGRect r = [lbl.text boundingRectWithSize:labelSize options:NSStringDrawingUsesLineFragmentOrigin attributes:#{NSFontAttributeName: font} context:context];
return r.size.height;
}
You can customize lbl on basis of your font and label size.
Have your label constrain the bounds of your cell, like your already doing. Be sure to include padding around it so it looks nicer.
In your heightForRowAtIndexPath: calculate the height required for your label (it is important you have your label correctly configured for multiline and/or word wrapping)
Calculate the required height of label
CGRect frame = [label.text boundingRectWithSize:CGSizeMake(cell.width, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:#{NSFontAttributeName: font} context:nil];
Return the calculated height plus padding
frame.size.height + TopPadding + Bottom Padding
This is a general approach to have a dynamically sizing cell.
Note: Sometimes this is off by a few points so you may need to add up 5 extra points in the cell height to get all the text fitting in the label.
Please write following line in viewDidLoad:
_tableView.rowHeight = UITableViewAutomaticDimension;
Please make sure of following points:
Dont create height constraint of label
Make width of that label equal to screen size or content view
Apply leading, trailing, top and bottom constraint
Dont write heightForRowAtIndexPath method
Please let me know the results
EDIT :
Write following line in your cellForRowAtIndexPath method
myLabel.preferredMaxLayoutWidth = cell.contentView.frame.size.width;

Calculate Cell height on basis of label text + image

I have created a custom cell that have IMAGE view, and two label's the data of labels's are populated from a plist file, the data is populated properly but on front end the cell didn't show the data properly, the label cut's the data. I am using Uilabel view's.
Please have a view to my code, i have search over internet and followed some tutorial's as well but nothing work's.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
Customviewcell *cell=[tableView dequeueReusableCellWithIdentifier:#"cell"];
UIImage * image = [UIImage imageNamed:justThumbs[indexPath.row]];
cell.CustomTitle.text=justTitles[indexPath.row];
cell.CustomTitle.numberOfLines =0;
[cell.CustomTitle sizeToFit];
cell.CustomDes.text=justDesc[indexPath.row];
cell.CustomDes.numberOfLines=0;
[cell.CustomDes sizeToFit];
[cell.CustomTitle layoutIfNeeded];
[cell.CustomDes layoutIfNeeded];
[cell layoutIfNeeded];
cell.Customimage.image=image;
return cell;
}
Code for calculating the height as per stackoverflow different question's answer's.
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
//Calculate Height Based on a cell
if (!self.customcell) {
self.customcell=[tableView dequeueReusableCellWithIdentifier:#"cell"];
}
// Configure Cell
UIImage * image = [UIImage imageNamed:justThumbs[indexPath.row]];
self.customcell.CustomTitle.text=justTitles[indexPath.row];
self.customcell.CustomTitle.numberOfLines=0;
[self.customcell.CustomTitle sizeToFit];
self.customcell.CustomDes.text=justDesc[indexPath.row];
self.customcell.CustomDes.numberOfLines=0;
[self.customcell.CustomDes sizeToFit];
self.customcell.Customimage.image=image;
//Layout Cell
//Get Hieght for the cell
if([[UIDevice currentDevice]userInterfaceIdiom]==UIUserInterfaceIdiomPhone)
{
if ([[UIScreen mainScreen] bounds].size.height == 568)
{
CGRect frame = [NSString setAttributeWithString:self.customcell.CustomTitle.text withLineSpacing:0.2 withSize:CGSizeMake(270, 999999999) withFont:self.customcell.CustomTitle.font withLabel:self.customcell.CustomTitle setLabelTextColor:self.customcell.CustomTitle.textColor setTextAlignment:self.customcell.CustomTitle.textAlignment];
self.customcell.CustomTitle.height.constant = frame.size.height;
frame = [NSString setAttributeWithString:self.customcell.CustomDes.text withLineSpacing:0.3 withSize:CGSizeMake(150, 999999999) withFont:self.customcell.CustomDes.font withLabel:self.customcell.CustomDes setLabelTextColor:self.customcell.CustomDes.textColor setTextAlignment:self.customcell.CustomDes.textAlignment];
self.customcell.CustomDes.height.constant = frame.size.height;
}
else{
CGRect frame = [NSString setAttributeWithString:self.customcell.CustomTitle.text withLineSpacing:1 withSize:CGSizeMake(337, 999999999) withFont:self.customcell.CustomTitle.font withLabel:self.customcell.CustomTitle setLabelTextColor:self.customcell.CustomTitle.textColor setTextAlignment:self.customcell.CustomTitle.textAlignment];
self.customcell.CustomTitle.height.constant = frame.size.height;
frame = [NSString setAttributeWithString:self.customcell.CustomDes.text withLineSpacing:1 withSize:CGSizeMake(227, 999999999) withFont:self.customcell.CustomDes.font withLabel:self.customcell.CustomDes setLabelTextColor:self.customcell.CustomDes.textColor setTextAlignment:self.customcell.CustomDes.textAlignment];
self.customcell.CustomDes.height.constant = frame.size.height;
}
}
[self.customcell layoutIfNeeded];
// CGFloat height = self.customcell.CustomTitle.height.constant+self.customcell.CustomDes.height.constant+189;
CGFloat height = [self.customcell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
//Add padding of 1
return height;
}
Used Github opensource library to solve the issue but didn't worked.
https://github.com/punchagency/line-height-tool
Issue still remain's, text of label's cut off, content hanging is at Required and Content is at 1000 horizontal + vertical..
Please help..
Thanks allot.
You can get the height of a string in certain bounds with the NSString method boundingRectWithSize, like
NSString* text = #"Test text";
CGRect textRect = [text boundingRectWithSize:CGSizeMake(300, CGFLOAT_MAX)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:#{NSFontAttributeName : [UIFont systemFontOfSize:12]}
context:nil];
CGFloat textHeight = ceilf(textRect.size.height);
Use your own font and font size, and you can also add other attributes to the attributes dictionary if necessary.
Use following method to calculate your UILabel height:
add also use this method in your class.
- (CGFloat)getLabelHeight:(UILabel*)label{
CGSize constraint = CGSizeMake(label.frame.size.width, CGFLOAT_MAX);
CGSize size;
NSStringDrawingContext *context = [[NSStringDrawingContext alloc] init];
CGSize boundingBox = [label.text boundingRectWithSize:constraint
options:NSStringDrawingUsesLineFragmentOrigin
attributes:#{NSFontAttributeName:label.font}
context:context].size;
size = CGSizeMake(ceil(boundingBox.width), ceil(boundingBox.height));
return size.height;}
Update your heightForRowAtIndexPath Method as per your requirement:
calculate all UI Height and return.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
Customviewcell *cell=[tableView dequeueReusableCellWithIdentifier:#"cell"];
CGFloat totalHeight = 0;
cell.CustomTitle.text=justTitles[indexPath.row];
//get label Height
totalHeight += [Helper getLabelHeight:cell.CustomTitle];
cell.Customimage.image = [UIImage imageNamed:justThumbs[indexPath.row]];
CGFloat imageHeight = cell.Customimage.frame.size.height; //or Add image height here
totalHeight += imageHeight;
return totalHeight;}
In iOS8+ you can use self sizing cells:
http://www.appcoda.com/self-sizing-cells/
Auto Resizing of Cell is available in Ios 8.0, The issue my deployment target was ios 7.0, which is causing the layout issues.
Please refer to these articles:
http://www.appcoda.com/self-sizing-cells/
The Code is in swift but need to do same thing's in objective c as well.
This will also help's you.
http://useyourloaf.com/blog/self-sizing-table-view-cells.html

Increase height of cell without configuring it?

I have so UITableView in that i have custom cell.That custom cell contains some labels .The text of label can be dynamic depending upon the Json. Now i want to make the height of cell based on the content height of the label so i have used the method heightForRowAtINdexPath.Now i am getting the cell like this.
if(!self.customCell)
{
self.customCell = [self.table_view dequeueReusableCellWithIdentifier:#"homeCell"];
}
the labels can be multiline depending upon the data.So i if write the same code of cellForRowAtiNdexPath in heightForRowAtIndexPath then i get more height.but if i don't write the same code then i get less height for labels.
as of now i have written below code for heightForRowAtIndexPath.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat height;
float like_height,c_one_height,c_two_height,c_three_height,tv_height,header_height,operations_height,img_like_icon_height,img_comment_icon_height,header_margin=5,tv_container_margin=5,operations_margin=5,like_top_margin=11,first_comment=10,second_comment=5,third_comment=5;
//define variables here
if(!self.customCell)
{
self.customCell = [self.table_view dequeueReusableCellWithIdentifier:#"homeCell"];
}
Post *user_post=[arr_post objectAtIndex:indexPath.row];
int like_count=[user_post.like_count intValue];
float comment_count=[user_post.comment_count intValue];
if (self.customCell.beizer_image != nil)
{
NSLog(#"inside cell beizer");
[self.customCell.beizer_image removeFromSuperview];
self.customCell.beizer_image=nil;
self.customCell.tv_post.textContainer.exclusionPaths=NULL;
self.customCell.beizer_path=nil;
}
[self.customCell setSelectionStyle:UITableViewCellSelectionStyleNone];
self.customCell.tv_post.text=user_post.post_description;
self.customCell.tv_post.font = [UIFont fontWithName:user_post.font_family size:[user_post.font_size floatValue]];
[self.customCell.tv_post setTextColor:[self colorFromHexString:user_post.font_color]];
if([user_post.post_image isEqualToString:#"none"] && [user_post.post_video isEqualToString:#"none"])
{
NSLog(#"NOT INSIDE THE CONDITION");
}
else
{
NSLog(#"INSIDE BEIZER PATH CONDITION");
self.customCell.beizer_path = [UIBezierPath bezierPathWithRect:CGRectMake(5, 5, 100, 100)];
self.customCell.tv_post.textContainer.exclusionPaths = #[self.customCell.beizer_path];
self.customCell.beizer_image =[[UIImageView alloc]initWithFrame:CGRectMake(5, 5, 100, 100)];
if(![user_post.post_image isEqualToString:#"none"])
{
[self.customCell.beizer_image setImageWithURL:[NSURL URLWithString:[IMAGE_BASE_URL stringByAppendingString:user_post.post_image]]placeholderImage:[UIImage imageNamed:#"post_placeholder.png"]];
}
if(![user_post.post_video isEqualToString:#"none"])
{
[self.customCell.beizer_image setImageWithURL:[NSURL URLWithString:[IMAGE_BASE_URL stringByAppendingString:user_post.post_video_thumbnail]]placeholderImage:[UIImage imageNamed:#"post_placeholder.png"]];
}
[self.customCell.tv_post addSubview:self.customCell.beizer_image];
}
//make textview height dynamic
self.customCell.tv_post.scrollEnabled=NO;
if([user_post.post_image isEqualToString:#"none"] && [user_post.post_video isEqualToString:#"none"])
{
CGFloat fixedWidth = self.customCell.tv_post.frame.size.width;
CGSize newSize = [self.customCell.tv_post sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)];
CGRect newFrame = self.customCell.tv_post.frame;
newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth), newSize.height);
self.customCell.tv_post.frame = newFrame;
self.customCell.tv_height.constant=self.customCell.tv_post.frame.size.height;
[self.customCell.view_tvContainer layoutIfNeeded];
}
else
{
CGFloat fixedWidth = self.customCell.tv_post.frame.size.width;
CGSize newSize = [self.customCell.tv_post sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)];
CGRect newFrame = self.customCell.tv_post.frame;
newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth),fmax(self.customCell.beizer_image.frame.size.height+10,newSize.height));
self.customCell.tv_post.frame = newFrame;
self.customCell.tv_height.constant=self.customCell.tv_post.frame.size.height;
[self.customCell.view_tvContainer layoutIfNeeded];
}
// self.customCell.f_comment_top.constant=-2100;
// [self.customCell layoutIfNeeded];
if(like_count>0)
{
like_height=self.customCell.label_like_count.frame.size.height;
}
else
{
like_height=0;
img_like_icon_height=0;
}
if(comment_count<=0)
{
c_one_height=0;
c_two_height=0;
c_three_height=0;
img_comment_icon_height=0;
}
else if(comment_count==1)
{
if(like_count<=0)
{
self.view.translatesAutoresizingMaskIntoConstraints = NO;
self.customCell.f_comment_top.constant=-21;
[self.customCell layoutIfNeeded];
}
c_one_height=self.customCell.first_comment.frame.size.height;
c_two_height=0;
c_three_height=0;
}
else if(comment_count==2)
{
if(like_count<=0)
{
self.view.translatesAutoresizingMaskIntoConstraints = NO;
self.customCell.f_comment_top.constant=-21;
[self.customCell layoutIfNeeded];
}
c_one_height=self.customCell.first_comment.frame.size.height;
c_two_height=self.customCell.second_cmment.frame.size.height+15;
c_three_height=0;
}
else if(comment_count==3)
{
if(like_count<=0)
{
// self.customCell.f_comment_top.constant=1020;
// [self.customCell.first_comment layoutIfNeeded];
}
else
{
}
c_one_height=self.customCell.first_comment.frame.size.height;
c_two_height=self.customCell.second_cmment.frame.size.height;
c_three_height=self.customCell.third_comment.frame.size.height+15;
}
tv_height=self.customCell.view_tvContainer.frame.size.height;
header_height=self.customCell.header_view_height.frame.size.height;
operations_height=self.customCell.view_operations_height.frame.size.height;
height = like_height+c_one_height+c_two_height+c_three_height+tv_height+operations_height+header_height;
CGFloat margin_height=header_margin+operations_margin+tv_container_margin+like_top_margin+first_comment+second_comment+third_comment+img_comment_icon_height+img_like_icon_height;
NSLog(#"like label height is %f",like_height);
NSLog(#"first comment height is %f",c_one_height);
NSLog(#"second comment height is %f",c_two_height);
NSLog(#"third comment height is %f",c_three_height);
NSLog(#"all margin height is %f",margin_height);
NSLog(#"height is %f",height);
// Padding of 1 point (cell separator)
height=height+margin_height;
CGFloat separatorHeight = 1;
return height;
}
I have seen many example in which it is written that for configuring cell the code of cellForRowAtIndexPath is written in heightForRowAtIndexPath.
Why i need to repeat the code for cellForRowAtIndexPath in
heightForRowAtIndexPath?
Why i need to repeat the code for cellForRowAtIndexPath in heightForRowAtIndexPath?
because heightForRowAtIndexPath will always get called before cellForRowAtIndexPath. So to calculate height in heightForRowAtIndexPath you have create that cell in heightForRowAtIndexPath.
Best way to use autolayout for dynamic height calculation:-
You can refer following Link to do the same.
There is no need to configure the entire cell which you have declared in cellForRowAtIndexPath in heightForRowAtIndexPath.
These are two methods used for specific functionality.
cellForRowAtIndexPath is a DataSource method which is meant for configuring your cell in tableview.
heightForRowAtIndexPath is a Delegate method which is meant to calculate the height of the tableviewcell or row based on the content which you are planning to show in cellForRowAtIndexPath.
For example, if you are configuring a cell with a UILabel (no matter how many labels) and assign the label with some text in cellForRowAtIndexPath, then in heightForRowAtIndexPath, fetch the text that you have assigned to label, calcluate label's height and give this height of the label to the cell. This will create the cell which have height according to your label's height.
For example, in your cellForRowAtIndexPath,
.....//your cell configuration code above//.....
UILabel *lbl_myText = [[UILabel alloc]initWithFrame:CGRectZero];
[lbl_myText setLineBreakMode:NSLineBreakByWordWrapping];
lbl_myText.minimumScaleFactor = FONT_SIZE;
[lbl_myText setNumberOfLines:0];
lbl_myText.textAlignment = NSTextAlignmentRight;
[lbl_myText setFont:[UIFont systemFontOfSize:FONT_SIZE]];
NSString *text = [arr_text objectAtIndex:indexPath.row];
CGSize constraint = CGSizeMake(Your_MAX_LabelWidth, Your_MAX_LabelHeight);
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
CGRect textRect = [text boundingRectWithSize:constraint
options:NSStringDrawingUsesLineFragmentOrigin
attributes:#{NSFontAttributeName:[UIFont systemFontOfSize:FONT_SIZE], NSParagraphStyleAttributeName: paragraphStyle.copy}
context:nil];
size = textRect.size;
[lbl_myText setText:text];
float widthIs = [lbl_myText.text
boundingRectWithSize:constraint
options:NSStringDrawingUsesLineFragmentOrigin
attributes:#{ NSFontAttributeName:lbl_myText.font }
context:nil]
.size.width;
[lbl_myText setFrame:CGRectMake(X_co,Y_co,widthIs,size.height)];
in heightForRowAtIndexPath:
.....//NO cell configuration code above//.....
NSString *cellText = [arr_text objectAtIndex:indexPath.row];
CGSize constraint = CGSizeMake(Your_MAX_LabelWidth, Your_MAX_LabelHeight);
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
////for message label
CGRect textRect = [cellText boundingRectWithSize:constraint
options:NSStringDrawingUsesLineFragmentOrigin
attributes:#{NSFontAttributeName:[UIFont systemFontOfSize:FONT_SIZE], NSParagraphStyleAttributeName: paragraphStyle.copy}
context:nil];
CGSize labelsize = textRect.size;
///calculate Cell the height
CGFloat height = MAX(labelsize.height, your_defaultcell_height);
if(height == your_defaultcell_height)
{
return your_defaultcell_height + 10; //10 is buffer height
}
else
{
return height + 10; //10 is buffer height
}

NSString sizeWithFont:constrainedToSize: computing wrong height

I have a Subtitle style UITableViewCell which height changes dynamically depending on the length of the text for each field. The problem is that the textLabel's height (CGSize size) does not increase if the label has multiple lines.
The weird part is that the detailTextLabel's height is increasing as it should (CGSize size2). The code to calculate both heights are identical.
Here is my function:
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
SETLISTFMNS0Song *song = [[[selectedSetlist.sets objectAtIndex:indexPath.section] songs]objectAtIndex:indexPath.row];
CGSize size = [song.name sizeWithFont:[UIFont fontWithName:setlistFont size:labelFontSize] constrainedToSize:CGSizeMake(self.setsTable.bounds.size.width, CGFLOAT_MAX)];
NSLog(#"Label: \"%#\" \tLabel Size: %f W %f H", song.name, size.width, size.height);
NSMutableString *detail;
if ([song cover]) {
detail = [[NSMutableString alloc] initWithFormat:#"(%# cover)", [[song cover] name]];
}
if ([song with]) {
if (!detail) {
detail = [[NSMutableString alloc] initWithFormat:#"(with %#)", [[song with] name]];
}
else {
[detail appendFormat:#" (with %#)", [[song with] name]];
}
}
if ([song info]) {
if (!detail) {
detail = [[NSMutableString alloc] initWithFormat:#"(%#)", [song info]];
}
else {
[detail appendFormat:#" (%#)", [song info]];
}
}
if (detail.length != 0) {
CGSize size2 = [detail sizeWithFont:[UIFont fontWithName:setlistFont size:detailFontSize] constrainedToSize:CGSizeMake(self.setsTable.bounds.size.width, CGFLOAT_MAX)];
size.height += size2.height;
NSLog(#"Detail Label: \"%#\" \tDetail Label Size: %f W %f H", detail, size2.width, size2.height);
}
return size.height + 5;
}
I am also setting both textLabel's numberOfLines property to 0 in cellForRowAtIndexPath to support multiple lines:
cell.textLabel.numberOfLines = 0;
cell.detailTextLabel.numberOfLines = 0;
UPDATE: Thanks to #josh I now understand why this is happening. I had the width constraints set to the width of the UITableView, which is too wide. Anyone know how to find the width of the UILabel before it is created? HA!
Thanks!
How long are the strings you're calculating the size against? I ask because you're sizeWithFont:constrainedToSize: function is constraining to the full width of the cell, but your labels are probably not the full width of the cell.
What I suspect is happening is song.info is just short enough that it would fit on one line if the line were the full width of the cell, and that your song detail is long enough that it is calculating the correct number of lines, but not so long as to exceed the calculated height.
All of that to say, I think what you need to do is find out the widths of textLabel and detailTextLabel and set your constraints to those values.
Update - A way of calculating label widths
Since the width of the labels inside of a cell are dependent on the width of the cell, and since cell's aren't created at the time heightForRowAtIndexPath: is called, we need to come up with a way to know the labels' widths before they the widths are set. The only way to do this is to set the widths ourselves. Here's how I would do it:
MyCell.h
#import <UIKit/UIKit.h>
#interface MyCell : UITableViewCell
+ (CGFloat)textLabelWidthForCellOfWidth:(CGFloat)cellWidth;
#end
MyCell.m
#import "MyCell.h"
#implementation MyCell
- (void)layoutSubviews {
[super layoutSubviews];
CGRect frame = self.textLabel.frame;
frame.size.width = [MyCell textLabelWidthForCellOfWidth:self.frame.size.width];
self.textLabel.frame = frame;
}
+ (CGFloat)textLabelWidthForCellOfWidth:(CGFloat)cellWidth {
// This calculation can be as complex as necessary to account for all elements that affect the label
return cellWidth - 20;
}
#end
Then in your heightForRowAtIndexPath: implementation you can call the same class method:
CGFloat labelWidth = [MyCell textLabelWidthForCellOfWidth:self.tableView.frame.size.width]; // Since non-grouped cells are the full width of the tableView
CGSize size2 = [detail sizeWithFont:[UIFont fontWithName:setlistFont size:detailFontSize] constrainedToSize:CGSizeMake(labelWidth, CGFLOAT_MAX)];
You would create a separate Class Method (+) for each label that you need to reference.
as looking at your code i found you are missing to define "lineBreakMode".
CGSize theSize = [song.name sizeWithFont:[UIFont fontWithName:setlistFont size:labelFontSize] constrainedToSize:CGSizeMake(self.setsTable.bounds.size.width, CGFLOAT_MAX) lineBreakMode:UILineBreakModeWordWrap];
update your code with this. i hope it will fix your problem. Good luck

Resize UITableViewCell to UILabel's height dynamically

I want to resize cell's height according to the label's height and label's height according to text. Or is there any way I can resize the cell's height according to the text entered in UITextView?
THIS METHOD IS DEPRECATED SINCE iOS 7.0.
There is a UITableView delegate method called heightForRowAtIndexPath that is called before you create a cell or a table.
You could use the NSIndexPath passed to it to get the text at a specific row and use the sizeWithFont method from UIStringDrawing.h to compute a CGSize for that row.
For example:
CGSize size = [text sizeWithFont:font
constrainedToSize:maximumLabelSize
lineBreakMode:UILineBreakModeWordWrap];
And finally you would return size.height.
--For iOS7--
Basing this off of Josh Vera's answer … place this in heightForRowAtIndexPath.
I have my table data stored in an NSArray *tableData.
// set the desired width of the textbox that will be holding the adjusted text, (for clarity only, set as property or ivar)
CGFloat widthOfMyTexbox = 250.0;
-(float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
//Get a reference to your string to base the cell size on.
NSString *cellText = [self.tableData objectAtIndex:indexPath.row];
//set the desired size of your textbox
CGSize constraint = CGSizeMake(widthOfMyTextBox, MAXFLOAT);
//set your text attribute dictionary
NSDictionary *attributes = [NSDictionary dictionaryWithObject:[UIFont systemFontOfSize:14.0] forKey:NSFontAttributeName];
//get the size of the text box
CGRect textsize = [cellText boundingRectWithSize:constraint options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil];
//calculate your size
float textHeight = textsize.size.height +20;
//I have mine set for a minimum size
textHeight = (textHeight < 50.0) ? 50.0 : textHeight;
return textHeight;
}
I haven't tested it for iOS<7, but I believe it should work for that as well.

Resources