Reputation: 4843
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...
Upvotes: 0
Views: 325
Reputation: 986
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];
//....
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;
}
//....
Upvotes: 2
Reputation: 562
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))];
}
Upvotes: 1