根据文本行自动计算标签的高度

Posted

技术标签:

【中文标题】根据文本行自动计算标签的高度【英文标题】:Calculate label's height automatically according to the line of text 【发布时间】:2015-11-18 03:59:56 【问题描述】:

到目前为止,我一直在计算自定义单元格高度。我需要在获取数据后自动调整单元格的大小。

self.countLabelself.descriptionLabel 只占用一行文本,另一方面,self.detailLabel 可能包含多行。所以下面的代码是我设置约束的方式。

CustomCell.m

- (void)initView

    self.countLabel = [UILabel new];
    self.countLabel.text = @"AAAAAA";
    self.countLabel.font = [UIFont fontWithPixel:22];
    self.countLabel.numberOfLines = 1;
    [self.contentView addSubview:self.countLabel];

    self.detailLabel = [UILabel new];
    self.detailLabel.text = @"Number of people: ";
    self.detailLabel.font = [UIFont fontWithPixel:22];
    self.detailLabel.textColor = [UIColor qu_grayColor];
    [self.contentView addSubview:self.detailLabel];

    self.descriptionLabel = [UILabel new];
    self.descriptionLabel.numberOfLines = 1;
    self.descriptionLabel.text = @"ABCDEFGHIJKLM";
    self.descriptionLabel.font = [UIFont fontWithPixel:26];
    [self.contentView addSubview:self.descriptionLabel];

    [self.countLabel mas_makeConstraints:^(MASConstraintMaker *make) 
        make.left.equalTo(self.contentView).offset(20);
        make.top.equalTo(self.contentView).offset(5);
        make.right.equalTo(self.contentView).offset(-10);
    ];

    [self.detailLabel mas_makeConstraints:^(MASConstraintMaker *make) 
        make.left.equalTo(self.contentView).offset(20);
        make.top.equalTo(self.countLabel.mas_bottom);
        make.bottom.equalTo(self.descriptionLabel.mas_top);
        make.right.equalTo(self.contentView).offset(-10);
    ];

    [self.descriptionLabel mas_makeConstraints:^(MASConstraintMaker *make) 
        make.left.equalTo(self.contentView).offset(10);
        make.right.equalTo(self.contentView).offset(-10);
        make.bottom.equalTo(self.contentView).offset(-15);

    ];

【问题讨论】:

如果您的目标是 ios 9+,这可以使用 stackviews 轻松完成。您需要在垂直堆栈视图中添加标签。使用自动布局将 stackview 定位在单元格中。 @TheAppMentor 哎呀,这个应用程序需要支持到iOS7.0。 【参考方案1】:
self.detailLabel.text = @"Number of peoples: ";
self.detailLabel.font = [UIFont fontWithPixel:22];
...
[self setLabelHeight:self.detailLabel];


- (void)setLabelHeight:(UILabel *)label 
    CGFloat fixedWidth = label.frame.size.width;
    CGSize newSize = [label sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)];
    CGRect newFrame = label.frame;
    newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth), newSize.height);
    label.frame = newFrame;



- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 
    //if indexPath.row == detailsLabelRow
    //return self.detailLabel.height
    //else 
    //return 1 line height

【讨论】:

@Wongzigii 获取数据并设置标签文本后,如果调用[self.tableView reloadData],这不起作用? 也制作label.numberOfLines = 0; @Wongzigii 使用 detailLabel 高度约束创建 IBOutlet 并更改例如self.hightConstraints.constant = 50; 【参考方案2】:

您必须首先将行数设置为零才能在UILabel 中有多行。

self.countLabel.numberOfLines = 0;

然后在设置文本调用波纹管方法之后。

[self.countLabel sizeToFit];

或者您可以创建类别类并在该类中添加以下方法。

-(void)setText:(NSString *)text 
    [super setText:text];
    [self sizeToFit];

如果你不需要到处调用它会很有帮助。

【讨论】:

【参考方案3】:

使用属性字符串

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath


//Calculating height on base of length of text
    UIFont *font =  [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
    NSAttributedString *attributedText =
    [[NSAttributedString alloc]
     initWithString:YOURSTRING //[NSString string withformat:@"\n Yourstring"] \n for: number of lines require for static label in cell
     attributes:@
     
     NSFontAttributeName: font
     ];
    CGRect rect = [attributedText boundingRectWithSize:(CGSize)CELL_CONTENT_WIDTH, CGFLOAT_MAX
                                               options:NSStringDrawingUsesLineFragmentOrigin
                                               context:nil];
    CGSize size = rect.size;

    //  NSString *height = [NSString stringWithFormat: @"%.2f", ceilf(size.height)+22];
    return (ceilf(size.height)+22)*0.6; //change 0.6 to 0.9 according to the difference in required and extra calculted height, it works for me every time

【讨论】:

【参考方案4】:

使用此方法制作单元格中标签的动态高度。并根据其他标签及其文本设置其框架。

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

    //Define Your Cell Here

    //Setting Properties of Labels Here Like this
    cell.countLabel.font = [UIFont systemFontOfSize:22];
    cell.countLabel.numberOfLines = 0;

    cell.detailLabel.font = [UIFont systemFontOfSize:22];
    cell.detailLabel.numberOfLines = 0;

    cell.descriptionLabel.numberOfLines = 0;
    cell.descriptionLabel.font = [UIFont systemFontOfSize:26];

    //Setting label's Text Here
    cell.countLabel.text = @"AAAAAA";
    cell.detailLabel.text = @"Number of people: ";
    cell.descriptionLabel.text = @"ABCDEFGHIJKLM";

    //Setting Label's Dynamic Height Using setlableFrame Method
    cell.countLabel = [self setlableFrame:cell.countLabel fontSize:22];
    cell.detailLabel = [self setlableFrame:cell.detailLabel fontSize:22];
    cell.descriptionLabel = [self setlableFrame:cell.descriptionLabel fontSize:26];

    //Setting Label's Frame According to Above Label
    cell.detailLabel.frame = CGRectMake(cell.detailLabel.frame.origin.x,       cell.countLabel.frame.size.height + cell.countLabel.frame.origin.y, cell.detailLabel.frame.size.width, cell.detailLabel.frame.size.height);

    cell.descriptionLabel.frame =  CGRectMake (cell.descriptionLabel.frame.origin.x, cell.detailLabel.frame.size.height + cell.detailLabel.frame.origin.y, cell.descriptionLabel.frame.size.width, cell.descriptionLabel.frame.size.height);

      return cell;

现在,单元格的动态高度使用以下方法。

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

     CGFloat myCellHeight = 0;//For Cell Height

     //For countLabel
     UILabel * myLabel = [[UILabel alloc] init];
     myLabel.frame = CGRectMake( 0, 0, 290, 21.0);//here set frame same as countLabel label's frame. make sure that, You must have setting width same as that label, otherwise you don't have accuracy for this.
     myLabel.numberOfLines = 0;
     myLabel.text = @"AAAAAA";
     myLabel = [self setlableFrame:myLabel fontSize:22.0];

     //Adding Height of countLabel
     myCellHeight = myLabel.frame.size.height;

     //For detailLabel
     myLabel.text = @"Number of people: ";
     myLabel = [self setlableFrame:myLabel fontSize:22.0];

     //Adding Height of detailLabel
     myCellHeight = myCellHeight + myLabel.frame.size.height;

     //For descriptionLabel
     myLabel.text = @"ABCDEFGHIJKLM";
     myLabel = [self setlableFrame:myLabel fontSize:26.0];

     //Adding Height of detailLabel
     myCellHeight = myCellHeight + myLabel.frame.size.height;

     return myCellHeight;

此方法用于根据文本制作标签的动态高度

//for setting the dynamic height of labels
-(UILabel *)setlableFrame:(UILabel*)myLabel fontSize:(float)size

    CGSize possibleSize = [myLabel.text sizeWithFont:[UIFont systemFontOfSize: size] constrainedToSize:CGSizeMake(myLabel.frame.size.width, 9999) lineBreakMode:NSLineBreakByWordWrapping];

    CGRect newFrame = myLabel.frame;
    newFrame.size.height = possibleSize.height;
    //If you want dynamic width of label, then uncomment following line
    //newFrame.size.width = possibleSize.width;
    myLabel.frame = newFrame;
    return myLabel;

【讨论】:

【参考方案5】:

您无需对动态高度执行任何这些操作。只需通过将高度大于等于标签的最小高度和其他对齐约束以及它们之间的垂直对齐来设置所有标签的约束。另外不要忘记将 0 设置为 Lines 属性,并将 Fixed Font Size 设置为 Autoshrink 属性。现在,当您为标签分配长文本时,只需调用

[self.view layoutIfNeeded];

标签会根据里面的文字增加高度。

【讨论】:

以上是关于根据文本行自动计算标签的高度的主要内容,如果未能解决你的问题,请参考以下文章

文本行/材质较大时如何自动扩展TextView的高度[关闭]

CSS标签显示模式 ④ ( 标签显示模式示例 | 设置行内元素宽高 | 设置鼠标经过样式 | 设置文字水平居中 | 设置文字垂直居中 | 文本行高与盒子高度关系 )

iOS给文本设置属性,并且计算文字行高

如何计算字体大小以适应单文本行和多行弹性项目上的文本?

自动布局 4 个 UILabel,根据其内容/文本垂直高度

根据 img 标签中给出的高度宽度自动裁剪图像