如何根据 iOS 中的内容更改 UILabel 高度

How to change UILabel height according to content in iOS

我在动态标签上遇到问题 height.My 要求如下图所示:

我正在参加 UIScrollView,在 UIScrollView 我正在添加 UILabel 以显示内容。我的内容是不同类型的文字大小。如果我设置 1 个内容,它会变得完美,但如果我在一个数组中获取内容,那么它会像下图一样出现:

有 6 个不同大小的文本内容。我实现了这个类型:

UIScrollView *scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 42, SCREEN_WIDTH, SCREEN_HEIGHT - 152)];
[scroll setBackgroundColor:[UIColor clearColor]];
[scroll setContentOffset:CGPointMake(0, 0)];
[scroll setShowsHorizontalScrollIndicator:NO];
[scroll setShowsVerticalScrollIndicator:NO];
[self.view addSubview:scroll];

contentArr = [[NSArray alloc] initWithObjects:@"Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla",@"Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",@"Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ",@"Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu",@"Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla",@"Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et ", nil];


float x_pos = 5;
float y_pos = 5;

for (int i = 0; i < contentArr.count; i ++)
{
    NSString *text1 = [contentArr objectAtIndex:i];
    CGSize constraint1 = CGSizeMake(152.5, 2000);
    CGSize size1 = [text1 sizeWithFont:[UIFont systemFontOfSize:12] constrainedToSize:constraint1 lineBreakMode:NSLineBreakByWordWrapping];

    NSLog(@"size1.height == %f",size1.height);

    UIView *bgView = [[UIView alloc] initWithFrame:CGRectMake(x_pos,y_pos,152.5,size1.height)];
    bgView.backgroundColor = APP_BGCOLOR;
    [scroll addSubview:bgView];

    [bgView.layer setBorderColor:[[UIColor colorWithRed:(170.0 / 255.0) green:(170.0 / 255.0) blue:(170.0 / 255.0) alpha:0.5] CGColor]];
    [bgView.layer setBorderWidth:1.0f];
    bgView.layer.cornerRadius = 4.0;
    bgView.layer.masksToBounds = YES;

    UILabel *lblComment = [[UILabel alloc] initWithFrame:CGRectMake(7,20,bgView.frame.size.width -14,bgView.frame.size.height - 20)] ;
    [lblComment setLineBreakMode:NSLineBreakByWordWrapping];
    lblComment.numberOfLines = size1.height/15;
    [lblComment setFont:[UIFont systemFontOfSize:10]];
    lblComment.text = text1;
    lblComment.backgroundColor = [UIColor clearColor];
    lblComment.tag = 1;
    [lblComment setNeedsDisplay];
    [bgView addSubview:lblComment];

    x_pos = x_pos + 157.5;

    if (x_pos > 300)
    {
        x_pos = 5;
        y_pos = y_pos + size1.height + 10;
    }

    [scroll setContentSize:CGSizeMake(SCREEN_WIDTH, y_pos)];
}

如果我只获取 1 个内容并在 For 循环之前为动态文本高度编写代码,那么它会像第二个图像一样出现。

我正在遵循此代码:

NSString *text1 = @"Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.";

CGSize constraint1 = CGSizeMake(152.5, 2000);
CGSize size1 = [text1 sizeWithFont:[UIFont systemFontOfSize:12] constrainedToSize:constraint1 lineBreakMode:NSLineBreakByWordWrapping];

如何解决这个问题?

如果有任何想法,请建议我...

有一些方法可以做到这一点:

#1 计算 textSize 然后设置标签:

- (CGSize)calculateSizeWithNSString:(NSString *)str {
  CGSize constraint1 = CGSizeMake(LABEL_WIDTH, FLT_MAX);
  UIFont *font = [UIFont systemFontOfSize:12];
  NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init];
  paragraph.lineBreakMode = NSLineBreakByWordWrapping;

  NSDictionary *attributesDictionary = [NSDictionary
      dictionaryWithObjectsAndKeys:font, NSFontAttributeName, paragraph,
                                   NSParagraphStyleAttributeName, nil];
  if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0f) {
  CGRect rect = [str boundingRectWithSize:constraint1
                             options:(NSStringDrawingUsesLineFragmentOrigin |
                                      NSStringDrawingUsesFontLeading)
                          attributes:attributesDictionary
                             context:nil];
    constraint1 = rect.size;
  } else {
        //sizeWithFont:constrainedToSize:lineBreakMode: was deprecated from iOS7.0
        constraint1 = [str sizeWithFont:font
                      constrainedToSize:constraint1
                          lineBreakMode:NSLineBreakByWordWrapping];
      }
      return constraint1;
    }

#2 将文本设置为标签,然后使用 sizeThatFit: 方法计算真实大小约束:

- (void)changeLabelSize:(UILabel *)label {
  CGRect labelFrame = label.frame;
  CGSize constraint1 = CGSizeMake(LABEL_WIDTH, FLT_MAX);
  CGSize expectSize = [label sizeThatFits:constraint1];
  labelFrame.size = expectSize;
  label.frame = labelFrame;
}

我认为 sizeThatFits: 在这种情况下比 [label sizeToFit] 更好,因为您想提供其中一个维度(列宽)作为参数:(非常感谢 Jef 纠正我)

apple doc

#编辑: 使用方法 2:

//.....
 // remove this line you dont need it any more
 CGSize size1 = [text1 sizeWithFont:[UIFont systemFontOfSize:12] constrainedToSize:constraint1 lineBreakMode:NSLineBreakByWordWrapping];
//...
[lblComment setFont:[UIFont systemFontOfSize:10]];
    lblComment.text = text1;
[self changeLabelSize:lblComment];
CGSize size1 = lblComment.frame.size; //for your calculate x_pos, y_pos code
[bgView addSubview:lblComment];
//....

编辑 2:x_pos、y_pos 计算

我有计算 x_pos、y_pos

的想法
    float col1_y_pos = 5;
    float col2_y_pos = 5;
    for (int i = 0; i < contentArr.count; i ++)
    {
        BOOL isColumn1 = (i%2 == 0)
        float x_pos = isColumn1 ? 5 : column2_x_pos_value;
        float y_pos = isColumn1 ? col1_y_pos: col2_y_pos;
        //your code set label frame with x_pos, y_pos
        //....
        CGSize size1 = lblComment.frame.size; 
        [bgView addSubview:lblComment];
        if (isColumn1) { 
           col1_y_pos += size1.height + marginTop;
        } else {
          col2_y_pos += size1.height + marginTop;
        }
   //....

您的文本有两栏。每行中的标签高度不同,您只有 1 个浮点数 y_pos 来设置标签位置。如果您可以看到第一列中的每个 label 都与第 2 列标签相等,只是因为您根据第 2 列维护 y_pos。您需要维护 y_posLeft y_posRight.

 float x_pos = 5;
    float y_posLeft = 5;
    float y_posRight = 5;

    for (int i = 0; i < contentArr.count; i ++)
    {
        NSString *text1 = [contentArr objectAtIndex:i];

//        UIView *bgView = [[UIView alloc] initWithFrame:CGRectMake(x_pos,y_pos,152.5,9999)];
//        bgView.backgroundColor = [UIColor lightGrayColor];
//        [scroll addSubview:bgView];

        UILabel *lblComment = [[UILabel alloc] initWithFrame:CGRectMake(x_pos, (i%2 == 1)?y_posRight:y_posLeft, 152.5, 1999)] ;
        [lblComment setLineBreakMode:NSLineBreakByWordWrapping];
        lblComment.numberOfLines = 0;
        [lblComment setFont:[UIFont systemFontOfSize:10]];
        lblComment.backgroundColor = [UIColor whiteColor];
        lblComment.text = text1;
        [self changeLabelSize:lblComment];
        CGSize size1 = lblComment.frame.size;
        [scroll addSubview:lblComment];

        [lblComment.layer setBorderColor:[[UIColor lightGrayColor] CGColor]];
        [lblComment.layer setBorderWidth:1.0f];
        lblComment.layer.cornerRadius = 4.0;
        lblComment.layer.masksToBounds = YES;
        if (x_pos == 5)
        {
            y_posLeft = y_posLeft + size1.height + 10;
        }
        else
        {
            y_posRight = y_posRight + size1.height + 10;
        }

        x_pos = x_pos + 157.5;

        if (x_pos > 300)
        {
            x_pos = 5;
        }


        [scroll setContentSize:CGSizeMake([[UIScreen mainScreen] bounds].size.width, MAX(y_posLeft, y_posRight))];
    }