将标签包裹在单元格中,宽度不好?

时间:2013-10-18 18:56:56

标签: ios uitableview autolayout

我正在尝试在静态内容表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。但这远远超出我的预期。

我也试过调用标签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}}
});

如何确定标签的宽度最终调用heightForRowAtIndexPath之前之前

1 个答案:

答案 0 :(得分:0)

您是否曾在此方法中调整行高?

-(void)tableView:(UITableView*)tableView willDisplayCell:(UITableViewCell*)cell forRowAtIndexPath:(NSIndexPath) {

在UITableView的一些内部工作方式之后调用它们,我们没有接触到它们已经运行并稍微“调整”了你的布局。

通常是对细胞视觉外观进行最终调整的正确位置。同样适用于及时性的要求也适用于此,您的代码应该非常灵活地提供所需信息,因此请确保您立即拥有所需的数据。