How do you dynamically resize two text label width

2019-06-01 02:09发布

问题:

I'm using a table view that uses a custom UITableViewCell subclass, NoteCell. The subclass has two text labels, a name label and a date label which are side-by-side in the cell. My goal is to have the name label resize itself so that the full date is shown no matter what.

in cellForRowAtIndexPath, I try to calculate and set the widths of the two text views so that the date is fully displayed and the name label is truncated.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"NoteCell";

    NoteCell *cell = (NoteCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    // Configure the cell...
    cell.dateLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin;

    cell.nameLabel.text = @"A name that should be truncated";
    cell.dateLabel.text = @"A long date to use as an example";

    // Set the widths
    // First calculate how wide the date label needs to be.
    cell.dateLabel.text = @"A really long date";
    CGSize dateLabelSize = [cell.dateLabel.text sizeWithFont:cell.dateLabel.font];
    CGFloat dateExpansionAmount = fabsf(dateLabelSize.width - cell.dateLabel.frame.size.width) + 10.0f;
    cell.dateLabel.frame = CGRectMake(cell.dateLabel.frame.origin.x - dateExpansionAmount,
                                      cell.dateLabel.frame.origin.y, 
                                      dateLabelSize.width, 
                                      cell.dateLabel.frame.size.height);

    CGFloat nameLabelWidth = cell.dateLabel.frame.origin.x - cell.nameLabel.frame.origin.x;
    cell.nameLabel.frame = CGRectMake(cell.nameLabel.frame.origin.x, 
                                      cell.nameLabel.frame.origin.y, 
                                      nameLabelWidth,
                                      cell.nameLabel.frame.size.height);
}

Unfortunately, the results are not correct because I don't think I'm setting/calculating the frame bounds correctly. See the image below.

Disregarding the problems with the frame calculations is there a better way to approach this problem or is manually positioning the text label frame the only way?

回答1:

try use this to set your dateLabel.

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

     static NSString *CellIdentifier = @"NoteCell";

    NoteCell *cell = (NoteCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    // Configure the cell...
    cell.dateLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin;

    cell.nameLabel.text = @"A name that should be truncated";
    cell.dateLabel.text = @"A long date to use as an example";

    //set frame cell.dateLabel
    CGSize maximumSize = CGSizeMake(INT_MAX, 44); // CGSizeMake(width,height).
    CGSize dateStringSize = [[cell.dateLabel.text sizeWithFont:[UIFont systemFontOfSize:cell.dateLabel.font]
                                                             constrainedToSize:maximumSize 
                                                                 lineBreakMode:UILineBreakModeWordWrap];

    CGRect dateFrame = cell.dateLabel.frame;
    dateFrame.size.width = dateStringSize. width;
    cell.dateLabel.frame = dateFrame;


return cell;
}


回答2:

after you set the text try to call the method "sizeToFit" and then you can just get the yourLabel.frame.size.width correctly, so if the 2 labels exceed the cell frame just resize the name label with a lower size and set correct position for the second, starting where the first one ends...

NEW EDIT (see comment)

cell.nameLabel.text = @"A name that should be truncated";
cell.dateLabel.text = @"A long date to use as an example";
[cell.nameLabel sizeToFit];
[cell.dateLabel sizeToFit];
// now check if the 2 width exceed cell size:
if (cell.nameLabel.frame.size.width + cell.dateLabel.frame.size.width > cell.frame.size.width){
//resize nameText:
cell.nameLabel.frame.size.width = cell.frame.size.width - cell.dateLabel.frame.size.width;
// ...and maybe consider to give it a minim size requirement
}
// now set the positions
cell.nameLabel.frame = CGRectMake(0,0,cell.nameLabel.frame.size.width,cell.nameLabel.frame.size.height );
cell.dateLabel.frame = CGRectMake(cell.nameLabel.frame.size.width,0,cell.dateLabel.frame.size.width,cell.dateLabel.frame.size.height );

ps be sure your autoresizingMask settings are corrected to top and left correctly for both labels