简体   繁体   中英

How to change UILabel height according to content in iOS

I am facing a problem on dynamic Label height.My requirement is like below image:

在此处输入图片说明

I am taking a UIScrollView and on UIScrollView I am adding UILabel for showing content. My content is different type of text size. If I set 1 content its coming perfect but if I take content within a Array then its coming like below image:

在此处输入图片说明

There are 6 content with different size of text. I implement this type:

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)];
}

If I take only 1 content and write code for dynamic text height before For loop then its coming like 2nd Image.

I am following this code:

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];

How to solve this issue?

If any idea, Please suggest me...

There are some ways you could do that:

#1 caculate textSize then set to label:

- (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 Set text to label then use sizeThatFit: method to calculate true size contraint:

- (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;
}

I think sizeThatFits: is a better option than [label sizeToFit] in this case because you want to supply one of the dimensions (the column width) as an argument: (big thank Jef for correct me)

See apple doc

#EDIT: Use method 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];
//....

EDIT 2: x_pos, y_pos calculate

I have an idea for calculate 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;
        }
   //....

You are having two columns for your texts. Labels in each row are different heights and you are having only 1 float y_pos to set label position. If you can see every label in first column is placed equal to column 2 label only because you are maintain y_pos according to 2nd column. You need to maintain 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))];
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM