如何根据文本标签长度动态设置表格单元格高度?

时间:2013-05-02 17:41:50

标签: ios objective-c uitableview

我正在尝试学习Obj-C和iOS编程,但我还是很新。我决定尝试制作一个简单的Reddit客户端应用程序。我试图在UITableView内显示首页帖子,每个帖子都由自己的单元格代表。

在单元格上,以下是我设置标题的方式:

cell.textLabel.numberOfLines = 0;
cell.textLabel.text = [[tempDictionary objectForKey:@"data"] objectForKey:@"title"];   
[cell.textLabel sizeToFit];

但是,如果标题文本太长,则单元格会自动剪切。这是一张图片:

enter image description here

如何让我的单元格自动调整其高度以适应更长的标题标签,而不会与其他单元格或详细文本标签相交?

感谢您的帮助!

4 个答案:

答案 0 :(得分:19)

对于新的iOS 8,有一种新方法可以实现这一点。

有一个新参数可根据您的自动布局约束计算单元格高度。这是UITableViewAutomaticDimension。您可以在视图控制器的viewWillAppear方法中使用它。

目标C:

- (void)viewWillAppear:(BOOL)animated {
  [super viewWillAppear:animated];
  self.tableView.estimatedRowHeight = 70.0; // for example. Set your average height 
  self.tableView.rowHeight = UITableViewAutomaticDimension;
  [self.tableView reloadData];
}

夫特:

override func viewWillAppear(animated: Bool) {
    self.tableView.estimatedRowHeight = 70 // for example. Set your average height 
    self.tableView.rowHeight = UITableViewAutomaticDimension
    self.tableView.reloadData()

} 

在您的榜样中,您可以随心所欲地工作。至于我,我在viewDidLoad中添加高度的东西,并在viewWillAppear中只添加reloadData()。还有用source

来自文档:The default value of rowHeight is UITableViewAutomaticDimension.我暂时保留代码,但请记住,您不需要在iOS 8 +中设置行高。

您需要做的主要是明确设置所有约束,例如到领先,尾随,顶部和底部。首先尝试一下,不要在上面添加任何代码行。

答案 1 :(得分:11)

您应该查看documentation reference

-[UITableViewDelegate tableView:heightForRowAtIndexPath:]

基本上,您需要自己测量文本,以便为每个表行返回正确的尺寸。如果它们很简单NSStrings,它们似乎来自您的屏幕截图,您可以使用NSString UIKit Additions来衡量它们,例如。

-[NSString sizeWithFont:constrainedToSize:]

约束大小可以具有无限高度但是表格单元格内容视图的宽度。

如果它们是属性字符串,则NSAttributedString UIKit添加中的类似方法称为boundingRectWithSize:options:context:

答案 2 :(得分:2)

我的应用TidBITS新闻确实完全你所描述的内容。而且我相信这是第一个弄明白如何的应用程序之一;至少,在我写这篇文章时,我知道没有其他应用程序可以做到这一点。我在我的编程iOS 4 书中发表了我的方法,从那以后它已经变得司空见惯了(虽然我并不是说每个人都从我那里得到它;基本上只有一种明智的方法来处理它)。

以下是我当前版本的解释:

http://www.apeth.com/iOSBook/ch21.html#_variable_row_heights

正如您所看到的,诀窍是通过调用标签上的sizeWithFont:constrainedToSize:来确定提前的所有行的高度,其中每个行都包含,并进行必要的数学运算。这是因为tableView:heightForRowAtIndexPath:将在前面,一遍又一遍地调用,以确定每个行的高度,之前要求您提供数据。

然后,当您被要求cellForRowAtIndexPath:时,您可以使用事先得出的结果,以便在您之前计算的高度内布置单元格。

Github上我还有一个可下载的完整项目示例,您可以阅读和运行;它向您展示了如何使用约束(仅限iOS 6及更高版本)。查找名称中包含ch21的{​​{1}}示例。

答案 3 :(得分:0)

在你的tableview中使用heightForRowAtIndexPath委托方法:

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

if (indexPath.row == 2) {
  Message *aMessage = [customTableViewArray objectAtIndex:indexPath.row];

  if ( [aMessage.msgBody length] <= 0 )
    aMessage.msgBody = @"     ";
    CGSize constraint = CGSizeMake(450, 40000.0f);
    CGSize size = [aMessage.msgBody sizeWithFont:[UIFont fontWithName:@"Helvetica" size:14] constrainedToSize:constraint lineBreakMode:UILineBreakModeCharacterWrap];
    size.height = MAX(size.height,36);

    return 136+size.height;

} else if(indexPath.row > 1) {

      Message *aMessage = [customTableViewArray objectAtIndex:indexPath.row];

      if ( [aMessage.msgBody length] <= 0 )
        aMessage.msgBody = @"     ";
        CGSize constraint = CGSizeMake(450, 40000.0f);
        CGSize size = [aMessage.msgBody sizeWithFont:[UIFont fontWithName:@"Helvetica" size:14] constrainedToSize:constraint lineBreakMode:UILineBreakModeCharacterWrap];
        size.height = MAX(size.height,36);

        return 100+size.height;

} else {
      return 146;
   }

}

我道歉,我只包含部分代码。这就是全部。所以基本上如果消息是空的,它会使它成为一个大小。然后在else if语句的一部分中,它获取消息的大小并将单元格大小基于该消息大小。