简体   繁体   中英

IOS Tableview custom cell with dynamic label height

I have trying to figure out this for quite some time :

I have a custom cell in tableview which has two labels one below other. The top label can be of one line or two line max. The bottom label is restricted to just one line.

The top label will always be there but the bottom label will be there for some cells and my not be there for some other cells.

I need a way to figure out how to arrange these labels centered vertically. I tried making the top label dynamic by using cell.label1.numberOfLines = 0; But then the label1 is not really restricted to 2 lines.

I tried to center these labels vertically by computing the height of first label and then arranging both labels centered.

If I restrict the number of lines to 2 using xib, then the height for first label always computes as 2 lines, even if the label consumes 1 line. One issue always which I see is if I use [cell.label1 sizeToFit]; then while scrolling the table the label always seem to change the text shown . The text shown is always for the respective label but the text sometimes wraps midway sometimes uses the full line.

Here is my code for reference :

CustomCell1 *cell = (CustomCell1 *)[self.tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomCell1" owner:self options:nil];
    cell = [nib objectAtIndex:0];
    cell.label1.lineBreakMode = UILineBreakModeWordWrap;
    cell.label1.numberOfLines = 0;
    cell.label1.tag = [indexPath row];
}
cell.label1.text = [[responseArray objectAtIndex:[indexPath row]] text];
if([[[responseArray objectAtIndex:[indexPath row]] isDone] isEqualToString:@"N"]) {
    cell.label2.text = @"";
} else {
    cell.label2.text = @"Done";
}

//[cell.label1 sizeToFit];

CGSize label1Size = [cell.label1 frame].size;
CGFloat label1Height = label1Size.height;
CGRect label1Frame = cell.label1.frame;
int numLines = (int)(label1Height/cell.label1.font.leading);

CGSize label2Size = [cell.label2 frame].size;
CGFloat label2Height = label2Size.height;
CGRect label2Frame = cell.label2.frame;

if(numLines > 1) {

    if([cell.label2.text isEqualToString:@""]) {
        //if label2 == "" then center label1
        label1Frame.origin.y = cellHeight/2 - label1Height/2;
        cell.label1.frame = label1Frame;
    } else {
        label1Frame.origin.y = 12;
        cell.label1.frame = label1Frame;
        label2Frame.origin.y = 52; 
        cell.label2.frame = label2Frame;
    }
} else {
    if([cell.label2.text isEqualToString:@""]) {
        CGRect frame = cell.label1.frame;
        frame.origin.y = cellHeight/2 - label1Height/2;
        cell.label1.frame = frame;
    } else {
        label1Frame.origin.y = cellHeight/2 - label1Height/2;
        cell.label1.frame = label1Frame;
        label2Frame.origin.y = cellHeight/2;
        cell.label2.frame = label2Frame;
    }
}

Please help me IOS gurus with your suggestions.

It would be better to move the resizing calculations to layoutSubviews.

//CustomCell.m

- (void)layoutSubviews{

CGRect label1Frame = self.label1.frame;
//Calculate the size of label 1
CGSize label1Size = [self.label1.text sizeWithFont:[self.label1 font]
                                constrainedToSize:CGSizeMake(label1Frame.size.width,42.0f)
                                    lineBreakMode:NSLineBreakByTruncatingTail];
label1Frame.size.height = label1Size.height;

CGRect label2Frame = self.label2.frame;
//Calculate the size of label 2
CGSize label2Size = [self.label2.text sizeWithFont:[self.label2 font]
                                 constrainedToSize:CGSizeMake(label2Frame.size.width,21.0f)
                                     lineBreakMode:NSLineBreakByTruncatingTail];
label2Frame.size.height = label2Size.height;

//Total height of labels
CGFloat totalHeight = label1Frame.size.height+label2Frame.size.height+5.0f;

//For centering half of difference of two labels with cell
label1Frame.origin.y = (self.frame.size.height - totalHeight)/2.0f;
self.label1.frame = CGRectIntegral(label1Frame);

label2Frame.origin.y = label1Frame.origin.y+label1Frame.size.height+5.0f;
self.label2.frame = CGRectIntegral(label2Frame);

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
     CustomCell1 *cell = (CustomCell1 *)[self.tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
     if (cell == nil)
     {
         NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomCell1" owner:self options:nil];
        cell = [nib objectAtIndex:0];
        cell.label1.lineBreakMode = UILineBreakModeWordWrap;
        cell.label1.numberOfLines = 2;
        cell.label1.tag = [indexPath row];
    }
    cell.label1.text = [[responseArray objectAtIndex:[indexPath row]] text];
    if([[[responseArray objectAtIndex:[indexPath row]] isDone] isEqualToString:@"N"]) {
        cell.label2.text = @"";
    } else {
        cell.label2.text = @"Done";
    }

    return cell;

}

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