【问题标题】:NSString sizeWithFont:constrainedToSize:lineBreakMode: differs from actual Label heightNSString sizeWithFont:constrainedToSize:lineBreakMode: 与实际标签高度不同
【发布时间】:2012-10-24 10:15:34
【问题描述】:

所以这里是怎么回事:我正在实现一个 UITableView(分组样式,有 1 个部分),以标准 UITableViewCells(样式 - UITableViewCellStyleSubtitle)作为内容。 我的 textLabel.text 可能很长,这就是为什么我在 TableView:cellForRowAtIndexPath: 中设置一些参数:

cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
cell.textLabel.numberOfLines = 0;
cell.textLabel.font = [UIFont boldSystemFontOfSize:CELL_FONT_SIZE];
cell.detailTextLabel.lineBreakMode = UILineBreakModeWordWrap;
cell.detailTextLabel.numberOfLines = 0;
[self configureCell:cell atIndexPath:indexPath];

为了调整单元格高度,我实现了 tableView:heightForRowAtIndexPath: 如下:

Test *test = (Test *)[self.frc objectAtIndexPath:indexPath];
NSString *cellText = test.test_name;

UIFont *cellFont = [UIFont boldSystemFontOfSize:CELL_FONT_SIZE];

CGFloat horizontalConstraint;
if (self.bagdePresent)
{
    // there will be big badge!
    horizontalConstraint = 250.0f;
} else
{
    // there will NO badge
    horizontalConstraint = 280.0f;
}

CGSize constraintSize = CGSizeMake(horizontalConstraint, MAXFLOAT);
CGSize labelSize = [cellText sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];

// return label height, 20 as gap, 30 for rating image,
return labelSize.height + 20 + 30;

首先我检查单元格中是否会有徽章图像,如果有,我会减少可用的水平空间。

这是问题(最后):对于某些字符串(某些字符串长度),当我将其文本属性设置为相同的字符串时,sizeWithFont:constrainedToSize:lineBreakMode: 返回的值小于实际单元格的 textLabel 高度。结果,如果单元格的 textLabels 大于单元格的边界。当我从显示错误的字符串中添加\删除一些单词时, sizeWithFont:constrainedToSize:lineBreakMode: 会给出精确的高度,稍后用 textLabel 实际高度确认。

我认为这可能是字体的问题,但正如您所见,字体是相同的。 从这里挖到哪里? ;)

UPD1: 下面是一个 textLabel 比在 heightForRowAtIndexPath 中计算的高的示例:

【问题讨论】:

    标签: objective-c ios string uitableview height


    【解决方案1】:

    我建议利用sizeToFit。首先,将标签的宽度设置为horizontalConstraint,然后调用[cell.textLabel sizeToFit](这将调整标签的高度以适应其内容,但保持设置的宽度(几乎-这意味着它可能成为窄一点):

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        CGFloat horizontalConstraint;
        if (self.bagdePresent)
        {
            // there will be big badge!
            horizontalConstraint = 250.0f;
        } else
        {
            // there will NO badge
            horizontalConstraint = 280.0f;
        }
    
        Test *test = (Test *)[self.frc objectAtIndexPath:indexPath];
        NSString *cellText = test.test_name;
    
        UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero];
        label.text = test.test_name;
        UIFont *cellFont = [UIFont boldSystemFontOfSize:CELL_FONT_SIZE];           
        label.lineBreakMode = UILineBreakModeWordWrap;
        label.numberOfLines = 0;
        label.font = cellFont;
    
        CGRect frame = label.frame;
        frame.size.width = horizontalConstraint;
        label.frame = frame;
        [label sizeToFit];
    
        CGSize labelSize = label.frame.size;
    
        // return label height, 20 as gap, 30 for rating image,
        return labelSize.height + 20 + 30;
    }
    

    【讨论】:

    • Tobi,感谢您的建议,但调用 cellForRowAtIndexPath: from heightForRowAtIndexPath: 创建无限循环:我正在尝试获取一个单元格,在返回它之前,TableView 想要获取它的高度......我是正在考虑从 heightForRowAtIndexPath: 获取单元格的另一种方法,但没有找到解决方案.. 你认为这可能吗?
    • 我没想到。我已经编辑了我的答案。只需创建一个新的UILabel,设置它的属性并从中获取高度。
    • 不幸的是,它不起作用,单元格的行为与以前一样。有趣的是,有一些边缘文本长度会导致这个问题。在您可以看到的图片上,当我向单元格文本添加一些字符时,它开始呈现正常(当我从中删除一些字符时也会发生同样的情况)。不知道下一步该去哪里......
    • 所以我通过修改约束值来“解决”这个问题,它现在以某种方式工作。但是当我开始采用代码来改变设备方向时,我会遇到同样的问题;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 2014-11-04
    • 2011-07-29
    • 1970-01-01
    • 1970-01-01
    • 2013-01-30
    • 1970-01-01
    相关资源
    最近更新 更多