具有动态标签高度的 IOS Tableview 自定义单元格

Posted

技术标签:

【中文标题】具有动态标签高度的 IOS Tableview 自定义单元格【英文标题】:IOS Tableview custom cell with dynamic label height 【发布时间】:2013-05-11 18:46:21 【问题描述】:

我已经尝试了很长时间了:

我在 tableview 中有一个自定义单元格,它有两个标签,一个在另一个之下。顶部标签最多可以是一行或两行。底部标签仅限于一行。

顶部标签将始终存在,但底部标签对于某些单元格将存在,而对于某些其他单元格则不存在。

我需要一种方法来弄清楚如何将这些标签垂直居中排列。我尝试使用 cell.label1.numberOfLines = 0; 使顶部标签动态化,但 label1 并没有真正限制为 2 行。

我尝试通过计算第一个标签的高度然后将两个标签居中排列来使这些标签垂直居中。

如果我使用 xib 将行数限制为 2,则第一个标签的高度始终计算为 2 行,即使标签占用 1 行。我看到的一个问题是,如果我使用[cell.label1 sizeToFit];,那么在滚动表格时,标签似乎总是会改变显示的文本。显示的文本始终针对相应的标签,但文本有时会在中途换行,有时会使用整行。

这是我的参考代码:

CustomCell1 *cell = (CustomCell1 *)[self.tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)

    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomCell1" owner:self options:nil];
    cell = [nib objectAtIndex:0];
    cell.label1.lineBreakMode = UILineBreakModeWordWrap;
    cell.label1.numberOfLines = 0;
    cell.label1.tag = [indexPath row];

cell.label1.text = [[responseArray objectAtIndex:[indexPath row]] text];
if([[[responseArray objectAtIndex:[indexPath row]] isDone] isEqualToString:@"N"]) 
    cell.label2.text = @"";
 else 
    cell.label2.text = @"Done";


//[cell.label1 sizeToFit];

CGSize label1Size = [cell.label1 frame].size;
CGFloat label1Height = label1Size.height;
CGRect label1Frame = cell.label1.frame;
int numLines = (int)(label1Height/cell.label1.font.leading);

CGSize label2Size = [cell.label2 frame].size;
CGFloat label2Height = label2Size.height;
CGRect label2Frame = cell.label2.frame;

if(numLines > 1) 

    if([cell.label2.text isEqualToString:@""]) 
        //if label2 == "" then center label1
        label1Frame.origin.y = cellHeight/2 - label1Height/2;
        cell.label1.frame = label1Frame;
     else 
        label1Frame.origin.y = 12;
        cell.label1.frame = label1Frame;
        label2Frame.origin.y = 52; 
        cell.label2.frame = label2Frame;
    
 else 
    if([cell.label2.text isEqualToString:@""]) 
        CGRect frame = cell.label1.frame;
        frame.origin.y = cellHeight/2 - label1Height/2;
        cell.label1.frame = frame;
     else 
        label1Frame.origin.y = cellHeight/2 - label1Height/2;
        cell.label1.frame = label1Frame;
        label2Frame.origin.y = cellHeight/2;
        cell.label2.frame = label2Frame;
    

请帮助我的 ios 专家提出您的建议。

【问题讨论】:

您应该使用 CustomCell 的layoutSubviews 来执行这些操作。求tableView:heightForRowAtIndexPath:中cell的高度,实现layoutSubviews 如何使用 layoutSubviews 来修复它。我不想动态更改单元格的高度,而是希望将单元格中的两个标签垂直居中。对不起,我是IOS的新手。如果我遗漏了什么,请解释一下。 你能检查我的答案吗? 【参考方案1】:

将调整大小的计算移到 layoutSubviews 会更好。

//CustomCell.m

- (void)layoutSubviews

CGRect label1Frame = self.label1.frame;
//Calculate the size of label 1
CGSize label1Size = [self.label1.text sizeWithFont:[self.label1 font]
                                constrainedToSize:CGSizeMake(label1Frame.size.width,42.0f)
                                    lineBreakMode:NSLineBreakByTruncatingTail];
label1Frame.size.height = label1Size.height;

CGRect label2Frame = self.label2.frame;
//Calculate the size of label 2
CGSize label2Size = [self.label2.text sizeWithFont:[self.label2 font]
                                 constrainedToSize:CGSizeMake(label2Frame.size.width,21.0f)
                                     lineBreakMode:NSLineBreakByTruncatingTail];
label2Frame.size.height = label2Size.height;

//Total height of labels
CGFloat totalHeight = label1Frame.size.height+label2Frame.size.height+5.0f;

//For centering half of difference of two labels with cell
label1Frame.origin.y = (self.frame.size.height - totalHeight)/2.0f;
self.label1.frame = CGRectIntegral(label1Frame);

label2Frame.origin.y = label1Frame.origin.y+label1Frame.size.height+5.0f;
self.label2.frame = CGRectIntegral(label2Frame);

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
     CustomCell1 *cell = (CustomCell1 *)[self.tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
     if (cell == nil)
     
         NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomCell1" owner:self options:nil];
        cell = [nib objectAtIndex:0];
        cell.label1.lineBreakMode = UILineBreakModeWordWrap;
        cell.label1.numberOfLines = 2;
        cell.label1.tag = [indexPath row];
    
    cell.label1.text = [[responseArray objectAtIndex:[indexPath row]] text];
    if([[[responseArray objectAtIndex:[indexPath row]] isDone] isEqualToString:@"N"]) 
        cell.label2.text = @"";
     else 
        cell.label2.text = @"Done";
    

    return cell;


【讨论】:

这个解决了我的问题!谢谢。

以上是关于具有动态标签高度的 IOS Tableview 自定义单元格的主要内容,如果未能解决你的问题,请参考以下文章

具有多行 UILabel 的自定义 Tableview 单元格需要动态高度

如何在 iOS 中创建具有动态 tableview 高度的动态 tableview 单元格

在tableview ios中使用UILabel的单元格的动态高度

具有自动布局的tableView中标签的高度问题

根据内容动态调整tableview单元格的高度 - iOS Swift

IOS Swift 5 为动态高度 TableView 单元添加自定义 TableViewCell 分隔符