我有一个视图控制器,它有一个UITableView实例,并使用自动布局约束来呈现它。我希望在这个表格视图中有可变的单元格高度。我不想自己计算细胞高度,因为我有一个复杂的细胞内容,由几个标签和图像组成,这些标签和图像可以因细胞而异。我相信可以让自动布局单元格调整自己的大小,使其包含所有子视图(即,在将文本分配给?之后,使用标签的sizeToFit方法)。
我有一个自定义单元格类,它使用自动布局的可视化约束格式来定位它的子视图。我尝试将这里提出的方法和它的示例实现合并在这里。
在初始化表视图时,我创建了一个数据行长度相等的数组,并通过将值赋给类型为MyCustomCell的原型单元格来计算每行的高度,并使用以下方法检索其高度
[cell systemLayoutSizeFittingSize:UILayoutFittingExpandedSize].height
并将其存储在heights数组中,以便稍后在表视图的heightForRowAtIndexPath方法中使用它来检索单个单元格的正确单元格高度。
但是,在执行所有这些操作时,我最终在xCode中出现了一个不可读的异常NSInternalInconsistencyException,其内容为“无法找到用于传入头myCustomCell:0xA8A1430.Width的传出行头,这永远不会发生。”
下面是我的自定义单元格中子视图的初始化:
_titleLabel = [[UILabel alloc] init];
_titleLabel.font = [TSTheme boldThemeFontOfSize:TSThemeFontSizeSmall];
_titleLabel.textColor = [[TSTheme sharedTheme] darkTextColor];
_titleLabel.backgroundColor = [UIColor clearColor];
_titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
_titleLabel.font = [UIFont fontWithName:@"HelveticaNeue-CondensedBold" size:19];
_titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
[self.contentView addSubview:_titleLabel];
_summaryLabel = [[UILabel alloc] init];
_summaryLabel.font = [TSTheme boldThemeFontOfSize:TSThemeFontSizeSmall];
_summaryLabel.backgroundColor = [UIColor clearColor];
_summaryLabel.textColor = [[TSTheme sharedTheme] darkTextColor];
_summaryLabel.translatesAutoresizingMaskIntoConstraints = NO;
_summaryLabel.numberOfLines = 0;
_summaryLabel.preferredMaxLayoutWidth = 250.0f; // required for text wrapping
_summaryLabel.font = [UIFont fontWithName:@"Georgia" size:14];
_summaryLabel.lineBreakMode = NSLineBreakByWordWrapping;
[self.contentView addSubview:_summaryLabel];
_thumbnailView = [[UIImageView alloc] init];
_thumbnailView.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addSubview:_thumbnailView];
和自定义单元格的约束如下所示
NSDictionary *views = NSDictionaryOfVariableBindings(_titleLabel, _summaryLabel, _thumbnailView);
NSDictionary *metrics = @{@"margin": @"5"};
[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(margin)-[_thumbnailView(<=60)]-(margin)-[_titleLabel]-(margin)-|"
options:0
metrics:metrics
views:views]];
[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(margin)-[_thumbnailView]-(margin)-|"
options:0
metrics:metrics
views:views]];
[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(margin)-[_titleLabel]-(0)-[_summaryLabel]"
options:0
metrics:metrics
views:views]];
[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(margin)-[_thumbnailView]-(margin)-[_summaryLabel]-(margin)-|"
options:0
metrics:metrics
views:views]];
当我使用一个表格视图单元格(它直接作为原型添加到情节提要中的UITableView)并使用DeQueueReusableCellWithIdentifier:获取用于缓存高度的单元格时,我遇到了这种情况。
如果我把单元格移到一个单独的笔尖中,那么它就实例化单元格来直接从笔尖上确定高度,这个问题就解决了。
然后可以向UITableView注册nib。希望这能帮上忙。
我使用这段代码来计算一行的高度,因为每一行的内容都不同:
-(CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ // Hacer que el tamaño de la celda sea variable dependiendo del tamaño del texto a mostrar
NoticiaAsignatura_DTO *rowData = [[NoticiaAsignatura_DTO alloc] init];
rowData = [self.listaNoticias objectAtIndex:[indexPath row]];
NSString *text = rowData.title;
text = [text stringByAppendingString:@"\n"];
text = [text stringByAppendingString: rowData.publish_date_ansi];
text = [text stringByAppendingString:@"\n\n"];
text = [text stringByAppendingString:rowData.content];
text = [text stringByAppendingString:@"\n\n"];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad){
CGSize constraint = CGSizeMake(700,200000.0);
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:NSLineBreakByWordWrapping];
return size.height + (CELL_CONTENT_MARGIN * 2);
}
else{
CGSize constraint = CGSizeMake(300,200000.0);
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE_PHONE] constrainedToSize:constraint lineBreakMode:NSLineBreakByWordWrapping];
NSLog(@"Size: %f ", size.height);
return size.height + (CELL_CONTENT_MARGIN * 2);
}
}
希望有帮助。
-
目标C:
// in ViewController.h
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
@property IBOutlet UITableView * table;
@end
// in ViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
self.table.dataSource = self;
self.table.delegate = self;
self.table.rowHeight = UITableViewAutomaticDimension;
self.table.estimatedRowHeight = UITableViewAutomaticDimension;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewAutomaticDimension;
}
斯威夫特:
@IBOutlet weak var table: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Don't forget to set dataSource and delegate for table
table.dataSource = self
table.delegate = self
// Set automatic dimensions for row height
table.rowHeight = UITableViewAutomaticDimension
table.estimatedRowHeight = UITableViewAutomaticDimension
}
// UITableViewAutomaticDimension calculates height of label contents/text
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
对于UITableviewCell中的label实例
注意:如果您有多个标签(uiellements)具有动态长度,应该根据其内容大小进行调整:对于您想要以更高优先级展开/压缩的标签,请调整“内容拥抱和压缩抵抗优先级”(content Hugging and Compression resistant priority)。