问题
I have a prototype cell inside my UITableView
which contains a UILabel
. I want to dynamically change the size of the label (and the cell) depending on the size of the text in the label.
I create the prototype cell in cellForRowAtIndexPath
like this:
static NSString *CellIdentifier = @"ProgramDetailCell";
ProgramDetailCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell.descriptionLabel.text = self.program.subtitle;
return cell;
Then my ProgramDetailCell
has the following implementation:
@implementation ProgramDetailCell
- (void)layoutSubviews {
[super layoutSubviews];
[self.descriptionLabel sizeToFit];
}
@end
The first time the cell is displayed, layoutSubviews
is called, but the descriptionLabel
does not get resized. However, if I scroll down the table and back up again, the "reused" cell appears with the label correctly resized!
Why does it not work the first time the cell is displayed - and what do I need to do to fix it.
Thanks in advance!
回答1:
In xib, go to first tab, under Interface Builder Document , uncheck use Auto Layout box.
回答2:
It doesn't work because you are using auto layout
. You need some auto layout
way to achieve this.
Here's the solution.
Step 1 :
Have the UILabel
Pinned to Top and Bottom of the UITableViewCell
. You can achieve this through the Interface Builder
by having Vertical Constraint
on UILabel
from top
and bottom
of the cell. This will make the UILabel
increase in height if the cell's height increase or vice versa.
Step 2:
In your UIViewController in - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
method calculate the size of the UITableViewCell
.
You can calculate it using :
CGRect textFrame = [YourText boundingRectWithSize:CGSizeMake(width of the label, FLT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:Your Font} context:nil];
now return the textFrame.size.height
+ padding if present.
Step 3 :
You will achieve what you wanted --- "dynamically change the size of the label (and the cell) depending on the size of the text in the label" after compiling and running even for the first time.
回答3:
After retrieving all data from server you can get height of that UILabel
using this method.
CGSize maximumSize = CGSizeMake(210, 9999);
for (int i = 0; i < [_arrProductList count]; i++) {
float row_height = 0.0f;
ProductInformation *product_obj = [_arrProductList objectAtIndex:i];
CGSize desc_size = [self measureHeightForText:product_obj.product_desc forFont: [UIFont systemFontOfSize:14] forSize:maximumSize];
row_height = row_height + desc_size.height;
// [_arrRowHeights addObject:[NSString stringWithFormat:@"%f", row_height]]; You can take it into array.
}
[tableView reloadData];
And here i have given description of measureHeightForText:
. This logic is working in all iOS5
,iOS6
,iOS7
.
-(CGSize)measureHeightForText:(NSString *)strText forFont:(UIFont *)font forSize:(CGSize)size{
if (!testingLabel) {
testingLabel = [[UILabel alloc] init];
// testingLabel.font = [UIFont fontWithName:[AppHandlers zHandler].fontName size:16];
testingLabel.text = @"";
testingLabel.numberOfLines = 0;
}
testingLabel.text =strText;
testingLabel.font = font;
CGSize expectedSize = [testingLabel sizeThatFits:size];
return expectedSize;
}
And then update size of your label according it. This is working fine for me. I am using it.
回答4:
Because when layoutSubviews
is called your descriptionLabel
's text is not set yet. And when you scroll, the text is set. So it is correct now.
I suggest you call sizeToFit
after you set the text.
static NSString *CellIdentifier = @"ProgramDetailCell";
ProgramDetailCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell.descriptionLabel.text = self.program.subtitle;
[cell.descriptionLabel sizeToFit];
return cell;
回答5:
Call this in heightForRowAtIndexPath
and manually calculate the height
static NSString *CellIdentifier = @"ProgramDetailCell";
ProgramDetailCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell.descriptionLabel.text = self.program.subtitle;
[cell.descriptionLabel sizeToFit];
return cell.descriptionLabel.frame.size.height+cell.descriptionLabel.frame.origin.y;
回答6:
You can use below code:
//Calculate the expected size based on the font and linebreak mode of your label
// FLT_MAX here simply means no constraint in height
CGSize maximumLabelSize = CGSizeMake(296, FLT_MAX);
CGSize expectedLabelSize = [yourString sizeWithFont:yourLabel.font constrainedToSize:maximumLabelSize lineBreakMode:yourLabel.lineBreakMode];
//adjust the label the the new height.
CGRect newFrame = yourLabel.frame;
newFrame.size.height = expectedLabelSize.height;
yourLabel.frame = newFrame;
回答7:
If your requirement is dynamically changing label height mean follow the below link. When we need to change height of label we need to change the row height also:
Resizing UILabel not quite working
回答8:
Use below code for dynamic height set in cell
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *messagetext=[NSString stringWithFormat:@"%@",[[arryStoryView objectAtIndex:indexPath.row] valueForKey:@"messagetext"]];
CGSize StoryTextSize= [messagetext sizeWithFont:[UIFont fontWithName:@"Georgia" size:17.0f] constrainedToSize:CGSizeMake(300, MAXFLOAT) lineBreakMode:NSLineBreakByWordWrapping];
int TotalHeight;
TotalHeight= StoryTextSize.height + 10;
return TotalHeight;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell1";
UITableViewCell *cell=[tblSendMsg dequeueReusableCellWithIdentifier:CellIdentifier];
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
NSString *storytext=[NSString stringWithFormat:@"%@",[[arryStoryView objectAtIndex:indexPath.row] valueForKey:@"storytext"]];
CGSize StoryTextSize = [storytext sizeWithFont:[UIFont fontWithName:@"Georgia" size:17.0f] constrainedToSize:CGSizeMake(300, MAXFLOAT) lineBreakMode:NSLineBreakByWordWrapping];
lblStoryText.frame=CGRectMake(5, 25, [[UIScreen mainScreen] bounds].size.width-10, StoryTextSize.height+30);
int nooflines=StoryTextSize.height/16;
int i= StoryTextSize.height;
if(i%16 !=0)
{
nooflines=nooflines+1;
}
lblStoryText.numberOfLines=nooflines;
lblStoryText.font=[UIFont fontWithName:@"Georgia" size:17.0f];
lblStoryText.text=[NSString stringWithFormat:@"%@",storytext];
return cell;
}
回答9:
If you are using autolayout, modifying the frame will have no effect.
Instead, you should modify the constraints.
来源:https://stackoverflow.com/questions/20996196/cannot-change-frame-of-a-uilabel-in-a-uitableviewcell-when-first-appearing-usin