将UITableViewCell的大小调整为其内容

时间:2014-11-14 13:57:27

标签: ios objective-c uitableview

我试图将UITableViewCell的尺寸调整为其内容。这基本上是用于聊天视图,我在其中列出所有先前的消息并允许用户滚动对话内容。

所以我有UITableView一些不同的细胞原型。传入的文本消息,传出的文本消息,传入的图像消息,传出的图像消息等。在每个单元格的内容视图中,我有一个标准的UIView,我打算用它来绘制聊天气球。这个视图几乎占据了单元格的内部空间(8px偏移到顶部,左侧,底部和右侧,四周都是)。在该视图中我想要内容。在文本单元格(传入和传出)的情况​​下,我想要一个显示文本消息的UITextView。这就是我的意思:

enter image description here

黄色是UIView,里面是UITextView。现在我想调整一切到文本的大小。我设法完成了以下任务:

  1. sizeToFit完全符合UITextView
  2. 所需的内容
  3. 我仍然不确定如何将UIView的尺寸调整为UITextView的尺寸。
  4. 要调整单元格的高度,我可以使用heightForRowAtIndexPath。我不需要(我认为不应该)调整单元格的宽度。但是有一些问题:这个方法何时被称为?该单元格是否已经实例化?它是否已经列出了子视图?否则,我该如何判断内容的大小?
  5. 对此的任何意见表示赞赏!

    编辑:

    我按照@vikingosegundo发布的教程设法取得了一些进展,但我再次陷入困境。这就是我所拥有的:

    enter image description here

    因此,基本上:文本视图具有前导,尾随,距离顶部和底部距离的约束。另一方面,包含视图具有尾随和距离顶部的约束,因此如果尺寸小,则它会向右捕捉。我不能有前导约束,否则它将始终占据细胞的整个宽度。我不确定距底限制的距离。

    当输入一条小信息时,它看起来很棒。它的尺寸合适,它向右移动。

    enter image description here

    然而,长消息不会跨越多行。相反,它仍然向右移动(OK),但宽度无限期地向左增长。

    enter image description here

    单元格已经将其高度调整为内容的高度:

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        HyConversationTableViewCell * cell = (HyConversationTableViewCell *)[self tableView:tableView cellForRowAtIndexPath:indexPath];
        CGSize size;
    
        [cell setNeedsLayout];
        [cell layoutIfNeeded];
    
        size = [cell.textMessageView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
    
        return size.height + 32;
    }
    

    我猜我现在需要的是文本视图的最大宽度等等,但我意识到这是不可能的。我该如何解决这个问题?

    编辑:如果我对包含视图有一个前导约束,那么当文本跨越多行时它看起来很棒,但是当它没有。这是它的样子:

    enter image description here

    enter image description here

    编辑:根据Alex Zavatone的建议,我将tableView:heightForRowAtIndexPath:更改为以下内容:

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        HyConversationTableViewCell * cell = (HyConversationTableViewCell *)[self tableView:tableView cellForRowAtIndexPath:indexPath];
    
        CGSize overflowSize = CGSizeMake(cell.textMessageView.frame.size.width, FLT_MAX);
        CGSize sizeAdjusted = [cell.textMessageView sizeThatFits:overflowSize];
    
        return sizeAdjusted.height + 32.0f;
    }
    

    由于高度已经调整,显示效果稍好,但行为有些不稳定。这是一开始的样子:

    enter image description here

    因此高度正确,但文本视图不会调整其宽度。此外,如果我将单元格滚出屏幕然后重新进入(这会强制它们重新绘制),它们会在似乎是随机标准的情况下开始表现不正常。这是一个样本:

    enter image description here

    有时这会发生在最后两个单元格中......

    编辑:最后一部分是通过将内容拥抱优先级和内容压缩阻力优先级设置为必需而将内部大小设置为占位符来修复的。现在高度显示正确。

3 个答案:

答案 0 :(得分:4)

如果您使用的是iOS 8,则可以使用UITableViewAutomaticDimension

您可以查看此example

self.tableView.rowHeight = UITableViewAutomaticDimension;

您还可以查看此video:2014 WWDC中表和集合视图中的新功能。

答案 1 :(得分:1)

在这里,我们是如何做到的

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{

    AFMediaWithHeadlineCell *cell = [[[NSBundle mainBundle] loadNibNamed:@"AFMediaWithHeadlineCell"
                                                                                   owner:nil
                                                                                 options:nil] firstObject];
   [cell loadText:@"Some text"];
   return [cell height];
}

实际上loadText:会将数据加载到用户界面,而sizeToFit就是这样。 和高度是计算单元格高度的基本方法

- (void)loadText:(NSString *)aText
{
     self.textView.text = aText;
     [self.textView sizeToFit];
}

- (CGFloat)height
{
    return self.textView.frame.origin.y + self.textView.frame.size.height + 10; // 10 is margin 
}

答案 2 :(得分:0)

您可以通过将高度设置为较大的数字然后在其上使用sizeThatFits来调整文本大小。

不是sizeToFit。

像这样:

    UILabel *label = self.prototypeCell.descriptiveText;
    label.numberOfLines = 0;
    CGSize sillyLargeHeight = CGSizeMake(label.frame.size.width, 9999);
    CGSize labelFrameAdjustedForHeight = [label sizeThatFits:sillyLargeHeight];
    return labelFrameAdjustedForHeight.height + 24.0; // 24 is 12 above and 12 below padding.

您可以使用标签或textView。如果您选择使用UILabel,则需要将#行设置为0,以使其为多行。

你可以在 - (CGFloat)tableView中执行此操作:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

您还需要进行相同的调整,以便在willDisplayCell方法中设置字段的高度(使用IBOutlet)。