0

我有一个 UITableViewCell 子类,它有一个图像、标题和描述。我应该根据描述内容长度调整单元格高度的大小,即如果它跨越超过 5 行,我应该扩展它(+其他子视图,如图像等)直到它持续。

下一个细胞应该在那之后才开始。

我有我的 UITableViewCell 子类从 xib 实例化,它具有固定的行高 = 160。

我知道这是非常标准的要求,但我找不到任何指导方针。

我已经像这样扩展了 layoutSubViews:

- (void) layoutSubviews
{
    [self resizeCellImage];
}

- (void) resizeCellImage
{
    CGRect descriptionRect = self.cellDescriptionLabel.frame;
    CGRect imageRect = self.cellImageView.frame;

    float descriptionBottomEdgeY = descriptionRect.origin.y +  descriptionRect.size.height;
    float imageBottomEdgeY = imageRect.origin.y + imageRect.size.height;

    if (imageBottomEdgeY >= descriptionBottomEdgeY)
        return;

    //push the bottom of image to the bottom of description
    imageBottomEdgeY = descriptionBottomEdgeY;

    float newImageHeight = imageBottomEdgeY - imageRect.origin.y;
    imageRect.size.height = newImageHeight;
    self.cellImageView.frame = imageRect;

    CGRect cellFrame = self.frame;
    cellFrame.size.height = imageRect.size.height + imageRect.origin.y + 5;

    CGRect contentFrame = self.contentView.frame;
    contentFrame.size.height = cellFrame.size.height - 1;
    self.contentView.frame = contentFrame;

    self.frame = cellFrame;
}

它几乎告诉我们,如果描述高于图像,我们必须调整图像的大小以及单元格高度以适应描述。

但是,当我通过这样做调用此代码时:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    cell.cellDescriptionLabel.text = @"Some long string";
    [cell.cellDescriptionLabel sizeToFit];
    [cell setNeedsLayout];

    return cell;    
}

看来,虽然单元格框架因layoutSubViews调用而改变,但其他单元格不尊重它。也就是说,如果前一个单元格不会自行调整大小,它们会出现在相同的位置。

两个问题:

  • 如何实现我想要的?
  • 我通过调用 inside 做得对setNeedsLayoutcellForRowAtIndexPath

PS:我知道heightForRowAtIndexPath改变单元格高度的关键,但我觉得我做的数据解析(此处未显示)cellForRowAtIndexPath只是为了计算高度而过度杀伤。我需要一些可以直接告诉UITableViewCell根据内容需要调整自身大小的东西。

4

3 回答 3

3

-tableView:heightForRowAtIndexPath:通过设计如何计算可变大小的单元格。单元格的实际框架并不重要,它会被表格视图更改以适应其需要。

你有点倒退了。委托告诉表格视图需要如何绘制单元格,然后表格视图强制单元格适应这些特征。您唯一需要提供给单元格的是它需要保存的数据。

这是因为表格视图在绘制任何单元格之前会计算所有单元格的所有高度。这样做是为了允许表格视图正确调整其滚动视图的大小。它允许适当大小的滚动条和通过表格视图平滑的快速平移。仅当表格视图认为需要将单元格显示到屏幕上时才会请求单元格。


更新:如何获得单元高度

我不得不这样做几次。我让我的视图控制器保留一个从未在表格视图中使用过的单元格。

@property (nonatomic) MyTableViewCell *standInCell;

然后,当我需要测量时,我会使用这个单元格作为替身。我确定了没有可变大小视图的单元格的基本高度。

@property (nonatomic) CGFloat standInCellBaseHeight;

然后在 中-tableView:heightForRowAtIndexPath:,我使用该索引路径的实际数据获取所有可变大小视图的高度。我将可变大小的高度添加到我的单元格基础高度中。我返回新计算的高度。

请注意,这都是非自动布局。我确信这种方法会相似,但与此不同,但我没有经验。

于 2014-01-28T19:32:45.490 回答
1

-tableView:heightForRowAtIndexPath:是告诉 tableview 其单元格大小的首选方法。您可以预先计算并将其缓存在字典中并重用,或者在 ios7 中,您可以使用它-tableView:estimatedHeightForRowAtIndexPath:来估计大小。

于 2014-01-28T22:24:09.577 回答
1

看看这个线程 - https://stackoverflow.com/questions/18746929/using-auto-layout-in-uitableview-for-dynamic-cell-layouts-variable-row-heights,答案指向一个非常好的此处的示例项目 - https://github.com/caoimghgin/TableViewCellWithAutoLayout

抱歉,但据我所知,您必须实施tableView:heightForRowAtIndexPath:. 警告,在 iOS 6 中,这会立即在 UITableView 中的每一行上调用,我想绘制滚动条。iOS7 引入tableView:estimatedHeightForRowAtIndexPath:了如果实现的话,您可以在进行所有计算之前只猜测高度。这对非常大的桌子有很大帮助。

我发现效果很好的只是让您tableView:heightForRowAtIndexPath:调用cellForRowAtIndexPath:以获取该行的单元格,然后查询该单元格的高度cell.bounds.size.height并返回。

这对于小表或在 iOS7 中非常有效tableView:estimatedHeightForRowAtIndexPath

于 2014-01-29T03:00:38.527 回答