具有可变高度的自定义单元格

Posted

技术标签:

【中文标题】具有可变高度的自定义单元格【英文标题】:Custom cell with variable height 【发布时间】:2012-03-03 03:34:50 【问题描述】:

我在 TableView 中使用自定义单元格。

单元格高度是根据加载到单元格的 UILabel 中的 NSString 计算的。 使用此函数计算大小

(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;

NSString *text = [self getTableViewRow:tableView index:indexPath];

CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);

CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];

CGFloat height = MAX(size.height, 44.0f);

return height + (CELL_CONTENT_MARGIN * 2) + 60;

大小计算正确,但是当单元格加载到 uiTableView 时,行的高度正确但单元格没有。

这是我创建单元格的地方

//Com Custom Cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

static NSString *simpleTableIdentifier = @"CustomCellIdentifier";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];

if (cell == nil) 

    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomCellApresentacao" owner:self options:nil];

    if ([nib count] > 0 )
        cell = self.tvCell;    
    else
        NSLog(@"Falhou a carregar o xib");
    

NSInteger row = [indexPath row];

if(self.myTableView1 == tableView)
    labelDescricaoApresentacao.text = [listData1 objectAtIndex:row];
else if (self.myTableView2 == tableView) 
    labelDescricaoApresentacao.text = [listData2 objectAtIndex:row];
else
    labelDescricaoApresentacao.text = [listData3 objectAtIndex:row];  

return cell;

我尝试使用此方法更改单元格高度

cell.frame.size.height

但它仍然没有加载正确的高度。

我必须在 customCell 的 xib 中做任何事情吗? 我应该如何将单元格高度更新为与行相同的大小?

【问题讨论】:

【参考方案1】:

你在哪里设置了 cell.frame.size.height?我建议尝试把它放在这里:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath 
    cell.frame = CGRectMake(0,0,320.0f,30.0f);

此方法在单元格显示之前被调用,是对单元格进行任何视觉更改的好地方。

【讨论】:

如果我把 cell.frame.size.height = 30.0f 例如他给出一个错误“表达式不可分配” cell.frame = CGRectMake(0,0,width,height)【参考方案2】:

即使您在heightForRowAtIndexPath 中正确设置了行的高度,但单元格的内容将始终具有固定的高度,因为您是从笔尖加载单元格的。要使单元格内容动态更改高度,您需要在cellForRowAtIndexPath 中以编程方式创建单元格及其子视图,使用与heightForRowAtIndexPath: 中相同的高度计算方法

【讨论】:

【参考方案3】:

我的猜测是您没有正确处理单元格的大小调整。

我不确定何时设置单元格的框架,但我猜它是在您从 tableView:cellForRowAtIndexPath: 方法返回一个单元格之后设置的,这意味着该单元格被创建或重用,然后它的框架是设置。

你应该做的是覆盖单元格的 setFrame: 方法,并在调用 super 之后修改它的子视图框架以适应新的大小。

您还可以在 Interface Builder 的子视图上使用自动调整大小的蒙版,以便它们自动适应新框架。

【讨论】:

【参考方案4】:

如果您从 NIB(或情节提要)加载原型单元格,它们的高度将与 UITableView 中定义的高度相同。

picciano 的解决方案在我的应用中不起作用。

我改用了这个委托函数,它可以工作:

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexpath
        CGFloat *theCellHeight=xxx;
        //determine here which section/row it is, and the desired height for it, put it in "theCellHeight"
        return theCellHeight;

希望对你有帮助,

备注:尽管如此,似乎没有办法获取单元格的内容/引用,因为在该函数中调用 cellAtIndexPath 时会冻结应用程序。因此,您必须以编程方式在数组中构建表,然后再创建它,这样会降低 NIB 的用处。

【讨论】:

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

使用 UITableView 的可变高度自定义单元格调用 reloadData 时保持 UITableView 的当前位置

自动布局:具有可变高度和两个标签的表格单元格

UITableview中的按钮修改当前单元格自定义

具有自动布局的自定义单元格的动态高度

具有静态单元的 UItableView 包含 2 个 UItableview,每个都有具有动态高度的自定义单元

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