如何根据NSString计算动态大小的UITableViewCells所需的高度

时间:2013-05-31 19:22:31

标签: objective-c uitableview

我有一个UITableView,它有自定义的UITableViewCells,这是用户的评论。现在,我有115.0f高的单元格,但我希望根据评论的时间长度改变高度。如果评论超过三行,我希望用户能够选择单元格,并且要扩展单元格以显示整个评论。我一直在使用[UIView animateWithDuration: completion:方法来扩展单元格,但我不知道如何根据文本的长度来确定单元格的正确大小。有人可以帮我吗?这是一些代码:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{    
    if (indexPath.row == 0)
    {
        return 480;
    }
    else
    {
        if (self.cellType == 0)
        {   
            return 115;
        }
        else
        {
            return 75;
        }
    }
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.row > 0)
    {
        NSIndexPath *path = [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section];
        UITableViewCell *cell = [tableView cellForRowAtIndexPath:path];
        if ([cell isKindOfClass:[CommentCell class]])
        {
            CommentCell *cell = (CommentCell *)[tableView cellForRowAtIndexPath:indexPath];
            UILabel *label = cell.commentBodyLabel;
            NSString *theText = label.text;
            CGSize constraintSize = CGSizeMake(label.frame.size.width, label.frame.size.height);
            CGSize labelSize = [theText sizeWithFont:label.font constrainedToSize:constraintSize lineBreakMode:label.lineBreakMode];
            CGFloat labelHeight = labelSize.height;
            int numLines = (int)(labelHeight/label.font.leading);
            NSLog(@"there are %i lines", numLines);
            NSLog(@"The text height is %f", labelHeight);
            if (numLines == 3)
            {
                //This is where I should expand the cell
            }
        }

2 个答案:

答案 0 :(得分:1)

查看NSString UIKit Additions

您对sizeWithFont:constrainedToSize:lineBreakMode:

特别感兴趣

将constrainedToSize属性的CGSize.width设置为单元格/标签区域的宽度。然后将CGSize.height设置为一个非常大的数字,可能是CGFLOAT_MAX。这个想法是你说的“嘿,这个标签必须适合一个静态宽度的区域,但它可以永久垂直。所以,告诉我这个标签实际上有多高,我给你的信息。“

NSString *comment = @"Some really long comment that does not fit in the standard cell size. This comment will be wrapped by word. Some more words to make this longer...";

CGSize renderedSize = [comment sizeWithFont:myFont constrainedToSize:CGSizeMake(kCellWidth, CGFLOAT_MAX) lineBreakMode:NSLineBreakByWordWrapping];

renderedSize.height是您为(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

返回的值

答案 1 :(得分:1)

一种方法是instantiate prototype cells,让他们根据给定的数据计算动态高度。通过此方法,您可以依赖故事板布局(如果您使用的是故事板),而无需在视图控制器中硬编码单元格配置的知识。

编辑我使用TLIndexPathTools添加了一个带有动态高度标签的单元格的工作示例,如果您的单元格实现了TLDynamicHeightView协议,它会自动为您计算动态高度。请参阅"Dynamic Height" example project。高度计算在单元格中完成,如下所示:

@interface DynamicHeightCell ()
@property (nonatomic) CGSize originalSize;
@property (nonatomic) CGSize originalLabelSize;
@end

@implementation DynamicHeightCell

- (void)awakeFromNib
{
    [super awakeFromNib];
    self.originalSize = self.bounds.size;
    self.originalLabelSize = self.label.bounds.size;
}

- (void)configureWithText:(NSString *)text
{
    self.label.text = text;
    [self.label sizeToFit];
}

#pragma mark - TLDynamicSizeView

- (CGSize)sizeWithData:(id)data
{
    [self configureWithText:data];
    CGSize labelSize = self.label.bounds.size;
    CGSize size = self.originalSize;
    size.width += labelSize.width - self.originalLabelSize.width;
    size.height += labelSize.height - self.originalLabelSize.height;
    return size;
}

@end

从本质上讲,您可以记住从故事板中唤醒单元格时的原始大小。然后,在执行计算时,在标签上调用sizeToFit并使用新大小计算高度增量并将其添加到原始高度。在故事板中,您需要将标签的宽度设置为所需的宽度,并将数字行设置为0.

在视图控制器方面,如果您正在使用TLIndexPathTools,则只需使用字符串数组设置数据模型,并在单元格上设置标签。原型和大小计算由基础TLTableViewController类自动完成。如果您不想使用TLIndexPathTools,那么从TLTableViewController提取位可以让您前进。

@implementation DynamicHeightTableViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.indexPathController.items = @[
          @"Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
          @"Fusce ac erat at lectus pulvinar porttitor vitae in mauris. Nam non eleifend tortor.",
          @"Quisque tincidunt rhoncus pellentesque.",
          @"Duis mauris nunc, fringilla nec elementum nec, lacinia at turpis. Duis mauris nunc, fringilla nec elementum nec, lacinia at turpis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.",
          ];
}

- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
    NSString *item = [self.indexPathController.dataModel itemAtIndexPath:indexPath];
    DynamicHeightCell *dynamicCell = (DynamicHeightCell *)cell;
    [dynamicCell configureWithText:item];
}