[英]UITableViewCell with autolayout left margin different on iPhone and iPad
[英]UITableViewCell Autolayout for Different Widths
我在有两个标签的情节提要中设置了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时看起来很糟糕。
可以(对自动排版有更多了解的人)请解释一下吗?
我假设您打算为每个标签使用多行文本。 UILabels需要知道他们会怎么宽,才能给出准确的高度时,它返回一个内在的内容大小。 可以通过设置preferredMaxLayoutWidth
来实现预期的行为,它可能有一个明显的局限性:使用“自动布局”的全部目的是您不一定需要或不想知道确切的值是什么。
您可以手动计算(如果不是始终是固定值)在某个时候与标签一起使用。 这对我来说是个笨拙的解决方案。
我更喜欢创建一个UILabel子类,该子类仅覆盖layoutSubviews
,该子类可以在布局时自动配置其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上设置一个自定义类,这将允许它使用此自定义类。
如果您使用的是iOS7 +,请尝试
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath{
}
代替
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.