systemLayoutSizeFittingSize: 和大小 类 的意外行为
Unexpected behavior of systemLayoutSizeFittingSize: and size classes
我有一些与动态大小的单元格、自动布局和大小 classes 有关的奇怪问题。我的测试项目完全基于 Ray 的教程。似乎唯一的区别是 UILabels 的字体大小为 classes。
当我为某种尺寸 class 的标签设置另一个字体大小时,高度计算是错误的。我做了截图来说明它。
W 单元格高度计算错误:
正确计算单元格高度:
此外,我已将 test project 推送到 github。
已编辑:
ViewController.m
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return [self heightForCellAtIndexPath:indexPath];
}
- (CGFloat)heightForCellAtIndexPath:(NSIndexPath *)indexPath {
static CustomTableViewCell *sizingCell = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sizingCell = [self.tableView dequeueReusableCellWithIdentifier:kBasicCell];
});
[self configurateCell:sizingCell atIndexPath:indexPath];
return [self calculateHeightForCell:sizingCell];
}
- (CGFloat)calculateHeightForCell:(CustomTableViewCell *)cell {
cell.bounds = CGRectMake(0.0f, 0.0f, CGRectGetWidth(self.tableView.frame), CGRectGetHeight(cell.bounds));
[cell setNeedsLayout];
[cell layoutIfNeeded];
CGSize size = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
return size.height +1.0f;
}
CustomLabel.m
- (void)setBounds:(CGRect)bounds {
[super setBounds:bounds];
if (self.numberOfLines == 0 && bounds.size.width != self.preferredMaxLayoutWidth) {
self.preferredMaxLayoutWidth = self.bounds.size.width;
[self setNeedsUpdateConstraints];
}
既然您已经在使用自动布局,我建议您也利用自动调整单元格的优势。您不需要任何行高计算,因为 iOS 可以根据 UILabel
高度自动调整单元格的高度。
- 将自动布局约束添加到您的 contentView
UILabel
。这将导致单元格根据标签的内容调整其 contentView
高度。
- 启用行高估计。
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 44.0;
有关详细信息,请参阅 smileyborg in his answer 到 Using Auto Layout in UITableView for dynamic cell layouts & variable row heights.
的详细演练
我有一些与动态大小的单元格、自动布局和大小 classes 有关的奇怪问题。我的测试项目完全基于 Ray 的教程。似乎唯一的区别是 UILabels 的字体大小为 classes。
当我为某种尺寸 class 的标签设置另一个字体大小时,高度计算是错误的。我做了截图来说明它。
W 单元格高度计算错误:
正确计算单元格高度:
此外,我已将 test project 推送到 github。
已编辑:
ViewController.m
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return [self heightForCellAtIndexPath:indexPath];
}
- (CGFloat)heightForCellAtIndexPath:(NSIndexPath *)indexPath {
static CustomTableViewCell *sizingCell = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sizingCell = [self.tableView dequeueReusableCellWithIdentifier:kBasicCell];
});
[self configurateCell:sizingCell atIndexPath:indexPath];
return [self calculateHeightForCell:sizingCell];
}
- (CGFloat)calculateHeightForCell:(CustomTableViewCell *)cell {
cell.bounds = CGRectMake(0.0f, 0.0f, CGRectGetWidth(self.tableView.frame), CGRectGetHeight(cell.bounds));
[cell setNeedsLayout];
[cell layoutIfNeeded];
CGSize size = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
return size.height +1.0f;
}
CustomLabel.m
- (void)setBounds:(CGRect)bounds {
[super setBounds:bounds];
if (self.numberOfLines == 0 && bounds.size.width != self.preferredMaxLayoutWidth) {
self.preferredMaxLayoutWidth = self.bounds.size.width;
[self setNeedsUpdateConstraints];
}
既然您已经在使用自动布局,我建议您也利用自动调整单元格的优势。您不需要任何行高计算,因为 iOS 可以根据 UILabel
高度自动调整单元格的高度。
- 将自动布局约束添加到您的 contentView
UILabel
。这将导致单元格根据标签的内容调整其contentView
高度。 - 启用行高估计。
self.tableView.rowHeight = UITableViewAutomaticDimension; self.tableView.estimatedRowHeight = 44.0;
有关详细信息,请参阅 smileyborg in his answer 到 Using Auto Layout in UITableView for dynamic cell layouts & variable row heights.
的详细演练