如何动态调整 UITableViewCell 内的两个文本标签宽度?

Posted

技术标签:

【中文标题】如何动态调整 UITableViewCell 内的两个文本标签宽度?【英文标题】:How do you dynamically resize two text label widths inside of a UITableViewCell? 【发布时间】:2012-02-24 23:30:33 【问题描述】:

我正在使用一个使用自定义 UITableViewCell 子类NoteCell 的表格视图。子类有两个文本标签,一个名称标签和一个日期标签,它们在单元格中并排排列。我的目标是让名称标签自行调整大小,以便无论如何都显示完整日期。

在 cellForRowAtIndexPath 中,我尝试计算并设置两个文本视图的宽度,以便完全显示日期并截断名称标签。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

    static NSString *CellIdentifier = @"NoteCell";

    NoteCell *cell = (NoteCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    // Configure the cell...
    cell.dateLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin;

    cell.nameLabel.text = @"A name that should be truncated";
    cell.dateLabel.text = @"A long date to use as an example";

    // Set the widths
    // First calculate how wide the date label needs to be.
    cell.dateLabel.text = @"A really long date";
    CGSize dateLabelSize = [cell.dateLabel.text sizeWithFont:cell.dateLabel.font];
    CGFloat dateExpansionAmount = fabsf(dateLabelSize.width - cell.dateLabel.frame.size.width) + 10.0f;
    cell.dateLabel.frame = CGRectMake(cell.dateLabel.frame.origin.x - dateExpansionAmount,
                                      cell.dateLabel.frame.origin.y, 
                                      dateLabelSize.width, 
                                      cell.dateLabel.frame.size.height);

    CGFloat nameLabelWidth = cell.dateLabel.frame.origin.x - cell.nameLabel.frame.origin.x;
    cell.nameLabel.frame = CGRectMake(cell.nameLabel.frame.origin.x, 
                                      cell.nameLabel.frame.origin.y, 
                                      nameLabelWidth,
                                      cell.nameLabel.frame.size.height);

不幸的是,结果不正确,因为我认为我没有正确设置/计算帧边界。见下图。

忽略框架计算的问题是否有更好的方法来解决这个问题,还是手动定位文本标签框架是唯一的方法?

【问题讨论】:

您是否已经尝试在询问的标签上设置 autoResize 属性? 您的意思是,设置自动调整大小属性,即支柱和弹簧? - 如果是的话,这将调整标签的大小以在设备旋转时展开或收缩。 您正确设置了日期标签的大小调整掩码,但未正确设置名称标签。它应该具有灵活的宽度和固定的右边距。 【参考方案1】:

尝试使用它来设置您的 dateLabel。

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    

     static NSString *CellIdentifier = @"NoteCell";

    NoteCell *cell = (NoteCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    // Configure the cell...
    cell.dateLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin;

    cell.nameLabel.text = @"A name that should be truncated";
    cell.dateLabel.text = @"A long date to use as an example";

    //set frame cell.dateLabel
    CGSize maximumSize = CGSizeMake(INT_MAX, 44); // CGSizeMake(width,height).
    CGSize dateStringSize = [[cell.dateLabel.text sizeWithFont:[UIFont systemFontOfSize:cell.dateLabel.font]
                                                             constrainedToSize:maximumSize 
                                                                 lineBreakMode:UILineBreakModeWordWrap];

    CGRect dateFrame = cell.dateLabel.frame;
    dateFrame.size.width = dateStringSize. width;
    cell.dateLabel.frame = dateFrame;


return cell;

【讨论】:

感谢您的回复! - 我已经尝试过这种方法,但发生的情况是日期标签从屏幕上移过披露指示器。基本上,由于您正在增加宽度,而不是加宽标签并将其向左扩展,它会向右增加宽度。 我也尝试过使用支柱和弹簧。我将原点锚点设置在右上角,而不是默认的左上角。我也设置了它,以便标签自动展开。仍然没有运气,因为我遇到了与上述相同的问题。【参考方案2】:

设置文本后尝试调用 方法“sizeToFit” 然后您可以正确获取 yourLabel.frame.size.width ,因此如果 2 个标签超过单元格框架,只需调整名称标签的大小,并为第二个设置正确的位置,从第一个结束的地方开始.. .

新编辑(见评论)

cell.nameLabel.text = @"A name that should be truncated";
cell.dateLabel.text = @"A long date to use as an example";
[cell.nameLabel sizeToFit];
[cell.dateLabel sizeToFit];
// now check if the 2 width exceed cell size:
if (cell.nameLabel.frame.size.width + cell.dateLabel.frame.size.width > cell.frame.size.width)
//resize nameText:
cell.nameLabel.frame.size.width = cell.frame.size.width - cell.dateLabel.frame.size.width;
// ...and maybe consider to give it a minim size requirement

// now set the positions
cell.nameLabel.frame = CGRectMake(0,0,cell.nameLabel.frame.size.width,cell.nameLabel.frame.size.height );
cell.dateLabel.frame = CGRectMake(cell.nameLabel.frame.size.width,0,cell.dateLabel.frame.size.width,cell.dateLabel.frame.size.height );

ps 确保两个标签的 autoresizingMask 设置都正确地更正为顶部和左侧

【讨论】:

我现在试一试,但我注意到的第一件事是sizeToFit 方法会调整标签的大小并将标签移出位置,这会产生它自己的一系列问题。您认为有没有更好的方法可以在不手动计算宽度的情况下实现这一目标? sizeToFit 调整 uilabel 框架的大小以消除未使用的空间。这样你就可以准确地知道你的文本有多大,现在“手动”计算它的宽度并不是那么困难......请参阅我的答案中的新编辑 好的,我试了一下,我已经很接近让它工作了 - 你的建议对 sizeToFit 很好。有一个挥之不去的问题。标签的原点是固定的,然后 sizeToFit 将扩展标签的框架以适应文本,但是(这就是问题所在)它将标签扩展到右侧而不是左侧,这意味着它会超出显示指示器的屏幕。标签需要向左扩展宽度,而不是向右... 是的,你是对的,这就是为什么你需要使用我的代码的最后两行(或者如果需要使用其他协调)

以上是关于如何动态调整 UITableViewCell 内的两个文本标签宽度?的主要内容,如果未能解决你的问题,请参考以下文章

除非滚动表格,否则 UITableViewCell 内的 UIView 调整大小不显示

如何使用 Swift 从 UITableViewCell 内的 NIB 调整自定义 UIView 的大小?

UITableViewCell内的UICollectionView如何根据屏幕大小调整tableview单元格高度

如何根据 UITableView 滚动动态调整 UITableViewCell 的大小?

UITableViewCell 内的 UIStackView 在 AutoLayout 上无法正确调整

UITableViewCell 无法根据它包含的动态 CollectionView 调整高度