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

问题描述:

我有一个UITableView具有自定义的UITableViewCells,它们是来自用户的评论。现在,我的单元格高达115.0f,但我希望根据评论的时间长度来改变高度。如果评论超过三行,我希望用户能够选择单元格,单元格可以展开以显示整个评论。我一直在使用[UIView animateWithDuration: completion:方法来展开单元格,但我不知道如何根据文本的长度计算出单元格的正确尺寸。有人可以帮我吗?下面是一些代码:如何根据NSString计算动态大小的UITableViewCells所需高度

- (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 
      } 
     } 

看看到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

该方法为renderedSize返回0。 –

一种方法是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]; 
} 
+0

最终他的问题是“但我不知道如何根据文本的长度计算出单元的正确大小。” –

+0

增加了一个工作示例。希望有所帮助。 –

+0

@ChrisWagner对不起,我正在组织一个工作示例来说明解决方案。 –