我在故事板中设置了一个UITableViewCell,它有两个标签,设置如下:
-----------------------
| ------------------- |
| | Label 1 | |
| ------------------- |
| ------------------- |
| | Label 2 | |
| ------------------- |
-----------------------
单元格的高度计算如下:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
int width = tableView.bounds.size.width - 30;
NSString *label1Text = ....;
NSString *label2Text = ....;
int label1Height = ceilf([label1Text boundingRectWithSize:CGSizeMake(width, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:17.0]} context:nil].size.height);
int label1Height = ceilf([label2Text boundingRectWithSize:CGSizeMake(width, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:17.0]} context:nil].size.height);
return 15 + label1Height + 1 + label2Text + 15;
}
这适用于故事板模板的宽度(例如320px)。当UITableViewController视图宽度变大(例如500px +)时,单元格采用正确的高度,但是标签1对于其内容变得太大(跨越1行文本超过2行)并且标签2变得压扁(跨越2行文字分为1行)。
但是,如果我在故事板中调整UITableViewController的大小(例如,宽度为500px)并更新标签的帧(保持相同的约束),则在加载视图时,它看起来很完美,宽度为500px,宽度为320px时非常糟糕。
有人(对自动布局有更多了解的人)请解释一下吗?
答案 0 :(得分:1)
我假设您打算为每个标签添加多行文本。 UILabels需要知道 的宽度,然后才能在返回内在内容大小时提供准确的高度。预期的行为可以通过设置preferredMaxLayoutWidth
来完成,它可能有一个明显的限制:使用自动布局的重点是你不一定需要或想知道确切的值是什么。
您可以手动计算(如果它并不总是固定值)您想要标签的某个点。这对我来说是一个笨重的解决方案。
我更喜欢创建一个仅覆盖layoutSubviews
的UILabel子类,它可以在布局时自动配置其preferredMaxLayoutWidth
。
// EBTSmartWidthLabel.h
#import <UIKit/UIKit.h>
@interface EBTSmartWidthLabel : UILabel
@end
然后
// EBTSmartWidthLabel.m
#import "EBTSmartWidthLabel.h"
@implementation EBTSmartWidthLabel
- (void)layoutSubviews
{
self.preferredMaxLayoutWidth = 0.0f;
[super layoutSubviews];
self.preferredMaxLayoutWidth = CGRectGetWidth(self.bounds);
[super layoutSubviews];
}
@end
代码首先将preferredMaxLayoutWidth
设置为0.0f,这使得UILabel尽可能宽。然后它执行实际布局,宽度将受到自动布局约束的限制。然后它取宽度(应该是最宽的(在您的情况下))并使preferredMaxLayoutWidth
然后再次执行布局。
这不一定是最有效的方式,在一些罕见/复杂/人为的情况下,可能导致大量的重新布局,但我已经取得了很好的效果。
如果您正在使用Storyboard / Interface Bulder,则可以在UILabel上设置自定义类,这将允许它使用此自定义类。
答案 1 :(得分:0)
如果您使用的是iOS7 +,请尝试
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath{
}
而不是
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
}