我正在尝试将多行标签包装在静态内容表 tableview 中,根据需要扩展行tableView:heightForRowAtIndexPath:
作为静态表,我可以设置IBOutlets
;我的标签是_instructionLabel
。
稍微简化一下(表中实际上有多行),它看起来像这样:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *labelText = _instructionLabel.text;
CGFloat labelWidth = _instructionLabel.frame.size.width;
CGSize constrainToSize = (CGSize){.width = labelWidth, .height = MAXFLOAT};
CGSize textSize = [labelText sizeWithFont:_instructionLabel.font constrainedToSize:constrainToSize lineBreakMode: _instructionLabel.lineBreakMode];
return textSize.height + 10;
}
(在我们继续之前:我知道UILabel
可能没有画到它的全宽。我计划稍后弄清楚如何补偿它,但这不是我的问题。)
问题来了:labelWidth
错了。在 iPad iOS 6 模拟器(纵向)上运行时捕获标签的屏幕截图,它的宽度约为 438 像素。我得到 638。(在 iOS 7 上,我得到 728。)
为了解决这个问题,我将这些行添加到viewWillAppear
:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear: animated];
[self.tableView setNeedsLayout];
[self.tableView layoutIfNeeded];
[self.tableView reloadData];
}
这会导致第二次通过表设置。现在,labelWidth
更接近:482。但这与我的预期相差甚远。
我也尝试过调用 label's sizeToFit
,但它似乎依赖于相同的错误数据。
我已经验证了标签的大小最终设置正确,方法是将其放入viewWillAppear
:
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
CGRect frame = _instructionLabel.frame;
NSLog(@"%@", NSStringFromCGRect(frame));
// Output: {{20, 0}, {438, 30}}
});
如何在 tableview 的最终调用之前和绘制之前确保标签的宽度设置正确?heightForRowAtIndexPath