首次出现时无法在 UITableViewCell 中更改 UILabel 的框架(使用自动布局)
Posted
技术标签:
【中文标题】首次出现时无法在 UITableViewCell 中更改 UILabel 的框架(使用自动布局)【英文标题】:Cannot change frame of a UILabel in a UITableViewCell when first appearing (using Autolayout) 【发布时间】:2014-01-08 12:51:24 【问题描述】:我的UITableView
中有一个原型单元格,其中包含一个UILabel
。我想根据标签中文本的大小动态更改标签(和单元格)的大小。
我在cellForRowAtIndexPath
中创建原型单元格,如下所示:
static NSString *CellIdentifier = @"ProgramDetailCell";
ProgramDetailCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell.descriptionLabel.text = self.program.subtitle;
return cell;
那么我的ProgramDetailCell
有如下实现:
@implementation ProgramDetailCell
- (void)layoutSubviews
[super layoutSubviews];
[self.descriptionLabel sizeToFit];
@end
第一次显示单元格时,会调用layoutSubviews
,但不会调整descriptionLabel
的大小。但是,如果我向下滚动表格并再次备份,则会出现“重用”单元格,并且标签的大小已正确调整!
为什么第一次显示单元格时它不起作用 - 我需要做些什么来修复它。
提前致谢!
【问题讨论】:
你找到解决这个问题的方法了吗? 找到解决这个问题的办法了吗? 【参考方案1】:在 xib 中,转到第一个选项卡,在 Interface Builder Document 下,取消选中使用自动布局框。
【讨论】:
这已经解决了这个问题,但现在我不能使用 AutoLayout。出路是什么? 好吧,你是对的。但是我需要在自定义 UITableViewCell 上使用自动布局,如何使用? 如果你想使用自动布局,这里重要的是约束。那么你不应该改变框架。请阅读此developer.apple.com/library/ios/documentation/UserExperience/…【参考方案2】:它不起作用,因为您使用的是auto layout
。你需要一些auto layout
方法来实现这一点。
这是解决方案。
第 1 步:
将UILabel
固定在UITableViewCell
的顶部和底部。您可以通过Interface Builder
实现此目的,方法是在单元格的UILabel
上设置Vertical Constraint
和top
和bottom
。如果单元格的高度增加,这将使UILabel
的高度增加,反之亦然。
第 2 步:
在你的 UIViewController 中 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
方法计算 UITableViewCell
的大小。
您可以使用:
CGRect textFrame = [YourText boundingRectWithSize:CGSizeMake(width of the label, FLT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:@NSFontAttributeName:Your Font context:nil];
现在返回textFrame.size.height
+ 填充(如果存在)。
第 3 步:
在第一次编译和运行之后,您将实现您想要的 --- “根据标签中文本的大小动态更改标签(和单元格)的大小”。
【讨论】:
第一个解决方案肯定对我有用。谢谢!【参考方案3】:从服务器检索所有数据后,您可以使用此方法获得UILabel
的高度。
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];
这里我给出了measureHeightForText:
的描述。此逻辑适用于所有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;
然后根据它更新标签的大小。这对我来说很好。我正在使用它。
【讨论】:
在 UITableView 委托调用之外更改标签的框架没有任何区别。你也在使用自动布局吗?【参考方案4】:因为当layoutSubviews
被调用时,您的descriptionLabel
的文本尚未设置。当你滚动时,文本被设置。所以现在是正确的。
我建议你在设置文本后拨打sizeToFit
。
static NSString *CellIdentifier = @"ProgramDetailCell";
ProgramDetailCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell.descriptionLabel.text = self.program.subtitle;
[cell.descriptionLabel sizeToFit];
return cell;
【讨论】:
【参考方案5】:在heightForRowAtIndexPath
中调用它并手动计算高度
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;
【讨论】:
谢谢,但这只会改变单元格的大小,而不是第一次显示标签时的大小。 是的,在 cellForRowAtIndexPath 中做同样的事情并返回单元格而不是高度 这也不起作用。标签第一次出现时,它会保留界面生成器的原始大小。【参考方案6】:您可以使用以下代码:
//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;
【讨论】:
我应该把这段代码放在哪里? cellForRowAtIndexPath? UITableViewCell 内的 layoutSubviews? cellForRowAtIndexPath 谢谢,但这没有用。框架的大小与首次出现时在 IB 中的大小相同,只有在滚动后重新显示单元格时才会更改为新大小。 我认为在标签上设置文字之前你已经写好了尺寸代码,你需要最后在标签上设置文字【参考方案7】:如果您的要求是动态更改标签高度,请点击以下链接。当我们需要改变标签的高度时,我们也需要改变行高:
Resizing UILabel not quite working
【讨论】:
我试过了,但没有帮助。你也在使用自动布局吗? 不,我没有使用自动布局。我为完整的应用程序编写了代码,没有使用 Xib 和 Storyboard。【参考方案8】:使用下面的代码在单元格中设置动态高度
- (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】:如果您使用自动布局,修改框架将无效。
相反,您应该修改约束。
【讨论】:
以上是关于首次出现时无法在 UITableViewCell 中更改 UILabel 的框架(使用自动布局)的主要内容,如果未能解决你的问题,请参考以下文章
首次加载 UITableViewController 时自定义 UITableViewCell 无法正确显示
UITableViewCell 上的圆形 UIImageView 在首次加载时不起作用
UITableViewCell 中的 UITextView 在 `textViewDidBeginEditing` 方法中首次分配失败
UIView 动画在 UITableViewCell 内无法正常工作
重新排序时无法从当前位置拖动 UITableViewCell
在 UiTableViewCell 上设置时,DisclosureButton Indicator 或任何类型的附件类型似乎都没有出现