在iOS8中查看表格单元格自动布局

我似乎无法让我的表格视图单元格上的AutoLayout工作。

在某些细胞上它似乎工作,而在其他细胞上似乎不起作用。 即使是完全相同的细胞。

例如,在某些单元格上,说明文字将超过1行,并且可以正常工作。

…然而,在其他单元格上,说明文字将超过1行,但只显示1行,并带有一堆空白空间。

你能帮我弄清楚我失踪或做错了什么吗? 谢谢!

我正在使用这个StackOverflow的问题来指导我的过程作为第一个计时器这样做: 在UITableView中使用自动布局dynamic单元格布局和variables行高

1.设置和添加约束

我相信大部分工作都很好。

2.确定唯一的表格视图单元重用标识符

我不完全确定是否需要担心这部分,因为我总是会有一个标题,时间和描述。

对于iOS 8 – 自定义单元格3.启用行高估计

我把这个添加到viewDidLoad

 self.tableView.rowHeight = UITableViewAutomaticDimension; self.tableView.estimatedRowHeight = 180.0; 

更新:每个Acey请求添加更多的信息 在这里输入图像说明

要清楚,我把约束:

  • 标题:左15,上85,右15
  • 标题和时间之间的垂直间距为10
  • 时间和描述之间的垂直间距为10
  • 我Cmd点击了所有三个标签,并添加了领先的边缘和拖尾边缘
  • 我在Description和Table View Cell的底部之间固定了20个字符

更新2:解决以下答案工作得很好,但也有任何额外的间距是由于单元格的高度设置太大,所以Xcode自动添加额外的空间来填充单元格的高度,因为文本标签没有填写完整的高度表视图单元格。

如果您遇到此问题并且遇到同样的问题,请告知我们是否有任何问题或需要帮助。

感谢大家!

我还没有尝试过使用新的iOS 8机制。 但是当我用iOS 6/7做这个时,我遇到了类似的问题。在将应用程序更新到iOS 8之后,它仍然可以正常工作,所以也许旧的方法仍然是最好的方法?

我在这里有我的代码的一些例子: AutoLayout多行UILabel切断一些文本

在这里: AutoLayout uitableviewcell在横向和iPad上计算基于纵向iPhone的高度

长话短说,保留一个单元格的副本,只是为了计算tableView:heightForRowAtIndexPath:的高度,前iOS 8的方式tableView:heightForRowAtIndexPath: 但是这对于处理多线UILabel是不够的。 每次调用layoutSubviews ,我都必须UILabel以更新preferredMaxLayoutWidth

preferredMaxLayoutWidth “fix”似乎是我错过的魔法秘密。 一旦我做到了这一点,我的大多数细胞工作完美。

第二个问题,我只要求我正确设置内容压缩抵抗和内容拥抱属性,所以例如告诉标签拥抱文本将意味着它不会扩大填充空白,这将导致单元格缩小。

一旦我做了这两件事情,我的单元格现在可以处理任何字体大小,或任何数量的文本没有任何凌乱的布局代码。 学习了很多东西,但是我认为最终还是有了回报,因为我的应用中有很多dynamic内容。

编辑

遇到我自己与iOS 8的几个问题后,我添加了一些更多的细节来解决这些非常奇怪的autoLayout错误。

用我提到的代码,当单元格“行高”未设置为自定义时,它似乎不起作用。 通过select单元格并单击autoLayout选项卡(其中所有内容压缩电阻设置等)在IB中find此设置。 按checkbox,它将填充一个临时的高度。

其次,在我的代码中,我保留了一个单元格的本地副本,然后在heightForRowAtIndexPath:方法内重复使用它多次。 这似乎每次调用时都会增加单元格的高度。 我必须通过调用以下命令重新初始化本地副本:

 localCopy = [self.tableView dequeueReusableCellWithIdentifier:@"mycell"]; 

看来新的Xcode 6 / iOS 8的变化是非常不能与iOS 7向后兼容的,而且它似乎被完全不同的pipe理。

希望这可以帮助。

编辑2

看完这个问题之后: iOS AutoLayout多行UILabel

我遇到了iOS 7 / iOS 8自动布局支持的另一个问题! 我重写了iOS 8的layoutSubviews我也需要重写setBounds来更新在调用super之后的preferredMaxLayoutWidth 。 跆拳道苹果改变了!

似乎是IB的preferredMaxLayoutWidth设置问题,因为iOS 7不能使用自动function,如果您在多个设备上使用相同的UILabel ,它将只使用1宽度。 因此,iOS 8平板电脑上的UITableViewCell将更大,因为同一个单元需要iOS 8 iPhone上的2行。

这是我的尝试。

你可以创build一个方法/函数来获得你需要的cellview。 像这样:

 - (UIView *) getCellView { UIView *cellView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, self.view.frame.size.width, 0.0f)]; cellView.tag = 1; cellView.backgroundColor = [UIColor clearColor]; UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(15.0f, 10.0f, 15.0f, 15.0f)]; //I assumed that was the size of your imageView; imgView.image = [UIImage imageNamed:@"whatever-your-image-is-called"]; [cellView addSubview:imgView]; CGFloat xPadding = 15.0f; CGFloat yPadding = 15.0f; UILabel *headlineLabel = [[UILabel alloc ]initWithFrame:CGRectMake(xPadding, 0.0f, self.view.frame.size.width - (xPadding*2), 0.0f)]; headlineLabel.numberOfLines = 0; headlineLabel.text = @"Red Sox season fell apart after World Series title (The Associated Press)"; [headlineLabel sizeToFit]; CGRect hFrame = headlineLabel.frame; if(hFrame.size.width > self.view.frame.size.width - 31.0f) hFrame.size.width = self.view.frame.size.width - 30.0f; hFrame.origin.y = imgView.frame.size.height + yPadding; headlineLabel.frame = hFrame; UILabel *timeLabel = [[UILabel alloc] initWithFrame:CGRectMake(xPadding, 0.0f, self.view.frame.size.height-(xPadding*2), 0.0f)]; timeLabel.text = @"4h"; //timeLabel.numberOfLines = 0; //uncomment if it will wrap on multiple lines; [timeLabel sizeToFit]; hFrame = timeLabel.frame; if(hFrame.size.width > self.view.frame.size.width - 31.0f) hFrame.size.width = self.view.frame.size.width - 30.0f; hFrame.origin.y = headlineLabel.frame.size.height + yPadding; timeLabel.frame = hFrame; UILabel *descriptLabel = [[UILabel alloc] initWithFrame:CGRectMake(xPadding, 0.0f, self.view.frame.size.height - (xPadding*2), 0.0f)]; descriptLabel.text = @"Boston (AP) -- To Boston Red Sox manager John Farrel, it hardly seems possible that just 11 months ago his team was celebrating the World Series championship on the field at Fenway Park."; descriptLabel.numberOfLines = 0; //I would suggest something like 4 or 5 if the description string vary from 1 line to more than 5 lines. [descriptLabel sizeToFit]; hFrame = descriptLabel.frame; if(hFrame.size.width > self.view.frame.size.width - 31.0f) hFrame.size.width = self.view.frame.size.width - 30.0f; hFrame.origin.y = timeLabel.frame.size.height + yPadding; descriptLabel.frame = hFrame; cellView.frame = CGRectMake(0.0f, 0.0f, self.view.frame.size.width, descriptLabel.frame.origin.y + descriptLabel.frame.size.height + 15.0f /*some padding*/); return cellView; } 

如果你正在使用indexPath.row,你可以改变方法名称为- (UIView *)getCellView:(NSIndex) *indexPath ,它应该是一样的。

然后在你的heightForRowAtIndexPath你可以做

return [[self getCellView] frame].size.height;

要么

return [[self getCellView:indexPath] frame].size.height

在你的cellForRowAtIndexPath中,你可以做下面的事情

 static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if(cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; cell.accessoryType = UITableViewCellAccessoryNone; cell.textLabel.text = @""; cell.detailTextLabel.text = @""; } [[cell viewWithTag:1] removeFromSuperview]; [cell addSubview:[self getCellView]; //or [cell addSubview:[self getCellView:indexPath]]; return cell; 

希望这可以帮助。 让我知道,如果有什么不清楚或不工作。 有一些东西,你可能需要调整,以适应您的使用,特别是在cellForRowAtIndexPath,但这应该是或多或less的一切,你需要去。 快乐的编码。