14

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

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

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

但是,如果标题文本太长,单元格最终会自行剪裁。这是一张图片:

在此处输入图像描述

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

感谢您的任何帮助!

4

4 回答 4

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

} 

在你的例子中工作得很好,就像你想要的那样。至于我,我只在 reloadData()viewDidLoad中添加高度的东西并留下。viewWillAppear还有有用的来源

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

您需要做的主要事情是明确设置所有约束,例如前导、尾随、顶部和底部。先试试看,上面不加任何代码行。

于 2014-08-09T23:21:27.887 回答
11

您应该查看文档参考

-[UITableViewDelegate tableView:heightForRowAtIndexPath:]

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

-[NSString sizeWithFont:constrainedToSize:]

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

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

于 2013-05-02T17:50:43.980 回答
2

碰巧我的应用 TidBITS News完全符合您的描述。而且我相信它是最早弄清楚如何做到这一点的应用程序之一。至少,在我写它的时候,我知道没有其他应用程序可以做到这一点。我在我的iOS 4 编程一书中发表了我的方法,从那时起它就变得司空见惯了(尽管我并不是说每个人都从我这里得到它;基本上只有一种明智的方法可以接近它)。

这是我的书当前版本的解释:

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

如您所见,诀窍是通过调用标签及其将包含在每行中的数据,并进行必要的数学运算,提前计算出所有行的高度。这是因为将在您被要求提供数据之前,一遍又一遍地预先调用以确定每一行的高度。sizeWithFont:constrainedToSize:tableView:heightForRowAtIndexPath:

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

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

于 2013-05-02T19:38:02.600 回答
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 部分中,它获取消息的大小并将单元格大小基于该消息大小。

于 2013-05-02T17:51:56.973 回答