2013-08-20 33 views
5

有很多关于SO和elsewhere的很好的信息,关于如何根据子视图的大小计算UITableView行所需的高度。典型的例子和我在这里应用的例子是一个包含可变长度文本标签的单元格。可变长度标签,tableview行高和自动布局

enter image description here

通常的建议是在tableview中的heightForRowAtIndexPath:使用sizeWithFont:constrainedToSize:lineBreakMode:。但是我见过的大多数例子都是基于已知的标签宽度使用“魔术”数字。

CGSize constraint = CGSizeMake(224.0, MAXFLOAT); //224 is known to be the width available 
CGSize labelSize = [cellText sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:NSLineBreakByWordWrapping]; 

一些更好的例子可能使用的tableview的边界,然后减去幻数或常数单元格中的其他意见,这至少是更清晰一点(如果边界改变旋转等效果更好) 。

CGSize constraint = CGSizeMake(self.tableview.bounds.size.width - 20 - 10 - 36 - 20, MAXFLOAT); //each non-label width subtracted 
CGSize labelSize = [cellText sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:NSLineBreakByWordWrapping]; 

这是常见的方法,但它似乎缺乏。谁能说其他单元格子视图的宽度,甚至是字体,都保证不会改变(或者在两个地方都会一直在努力改变)?

我决定宁愿让单元格负责提供这个高度。细胞总是知道它的属性。为了达到这个目的,我首先将单元格中的所有布局代码都引用了一些局部常量。然后,我在自定义单元类中添加了一个类方法,该类可以根据自己的字体和调整常量返回给定文本所需的高度。

+ (CGFloat)heightRequiredForText:(NSString *)text usingWidth:(CGFloat)width 
{ 
    //a class method that tells the caller how much height is needed for the provided text, based on the cell's size and font constants 
    CGSize constraintSize = CGSizeMake(width - kMargin - kGap - kMargin - kCheckboxWidth, MAXFLOAT); 
    CGRect bounds = [text boundingRectWithSize:constraintSize 
               options:NSStringDrawingUsesLineFragmentOrigin 
              attributes:@{NSFontAttributeName:self.labelFont} 
               context:nil]; 
    return bounds.size.height; 
} 

这允许UITableViewController只提供文本和当前边界的宽度(即tableview的宽度)。字体和布局可以在单元格子类中更改,并且所有内容都继续“正常工作”。

问题1

正如一个方面说明,这是合理的?有没有更好的方法来实现相同的目标?

问题2

这里是我与这个具有主要问题(和更标准)的做法。当单元格处于其编辑模式时,标签宽度会发生变化以适应编辑附件。由于行高不变,并且标签使用自动布局,因此其高度会增加。

enter image description here

所需行为是标签的高度保持恒定和截断时,应使用必要的。

在哪里以及如何实现?我应该在单元格的编辑中做些什么:?也许增加另一个约束来限制高度,并打开截断,在编辑== NO时应用相反的约束?怎么样'刷卡删除'模式 - 我不认为这触发setEditing?怎么样layoutSubview - 我可以在那里做点什么?

+0

我推荐的方法是使用[原型单元例(http://stackoverflow.com/questions/13660004/retrieve-custom -prototype-cell-height-from-storyboard/14127936#14127936)这种事情。 –

回答

1

我尝试了很多东西 - 我得到的最接近的是重写layoutSubviews,测试用户是否切换到编辑模式,如果是这样,先捕获标签的内在高度,然后添加一个临时约束来强制执行它然后在脱离编辑模式时被移除)。除了一些边缘情况,它运作良好。

但后来我开始考虑更多的汽车布局。我想达到什么目的?当宽度减小时,我不希望标签变长。这是一个非常简单的约束:

[self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:self.label 
                    attribute:NSLayoutAttributeHeight 
                    relatedBy:NSLayoutRelationLessThanOrEqual 
                     toItem:self.contentView 
                    attribute:NSLayoutAttributeHeight 
                    multiplier:1 
                    constant:0]]; 

添加这个额外的约束效果很好。请注意,我也转换行模式截断上编辑:

enter image description here

相关问题