UITableViewCell with dynamic height iOS

前端 未结 12 2285
日久生厌
日久生厌 2020-11-27 17:54

I have implemented TableView with CustomCell in my app,

I want dynamic height of my UITableViewCell according to text length in UITableViewCell

相关标签:
12条回答
  • 2020-11-27 18:38

    A'm looking for a long time how to determinate cell height properly, - looks like - it's a best solution, boundingRectWithSize and constrainedToSize often incorrectly calculated text height, you need to create UILabel than use sizeThatFits function, see below

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
        {
    
        UILabel  * label = [[UILabel alloc] initWithFrame:CGRectMake(8, 5, celllabelWidth, 9999)];
        label.numberOfLines=0;
        label.font = [UIFont fontWithName:fontName size:textSize];
        label.text = @"celllabelTextHere";
    
        CGSize maximumLabelSize = CGSizeMake(celllabelWidth, 9999);
        CGSize expectedSize = [label sizeThatFits:maximumLabelSize];
        return expectedSize.height;
    }
    
    0 讨论(0)
  • 2020-11-27 18:38

    Refer this link you are using Autolayout

    else you can use below approach

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    
    NewsVCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
    
    if (cell == nil)
    {
    
        cell = [[NewsVCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];
    
    }
    
    cell.titleCell.numberOfLines = 0;
    cell.descriptionCell.numberOfLines = 0;
    
    cell.titleCell.font = [UIFont systemFontOfSize:12.0f];
    cell.descriptionCell.font = [UIFont systemFontOfSize:12.0f];
    
    cell.descriptionCell.textColor = [UIColor lightGrayColor];
    
    
    CGSize maximumLabelSize;
    
    if([UIDevice currentDevice].userInterfaceIdiom==UIUserInterfaceIdiomPad || [[[UIDevice currentDevice] model] isEqualToString:@"iPad Simulator"])
    {
        maximumLabelSize = CGSizeMake(768, 10000);
    
    }
    else
    {
        maximumLabelSize = CGSizeMake(270, 10000);
    
    }
    
    NSString *newsTitle =  [[feeds objectAtIndex:indexPath.row] objectForKey: @"title"];
    
    NSString *descriptionsText = [[feeds objectAtIndex:indexPath.row] objectForKey: @"description"];
    
    
    CGSize expectedTitleLabelSize = [newsTitle sizeWithFont: cell.titleCell.font constrainedToSize:maximumLabelSize lineBreakMode:cell.titleCell.lineBreakMode];
    
    CGSize expectedDescriptionLabelSize = [descriptionsText sizeWithFont:cell.descriptionCell.font constrainedToSize:maximumLabelSize lineBreakMode:cell.descriptionCell.lineBreakMode];
    
    NSLog(@"cellForRowAtIndexPath :indexpath.row %d: height expectedTitleLabelSize:%f , indexpath.row height expectedDescriptionLabelSize:%f",indexPath.row,expectedTitleLabelSize.height,expectedDescriptionLabelSize.height);
    
    
    
    if (newsTitle.length > 0)
    {
    
        cell.titleCell.frame = CGRectMake(20.0f, 10.0f, 270.0f ,expectedTitleLabelSize.height+20.0f);
    
    }
    else
    {
         cell.titleCell.frame = CGRectMake(20.0f, 10.0f, 270.0f ,expectedTitleLabelSize.height-20.0f);
    }
    
    
    if (descriptionText.length > 0)
    {
        cell.descriptionCell.frame =  CGRectMake(20.0f, 10.0f + cell.titleCell.frame.size.height, 270.0f, expectedDescriptionLabelSize.height+20.0f);
    
    }
    else
    {
        cell.descriptionCell.frame =  CGRectMake(20.0f, cell.titleCell.frame.size.height, 270.0f, 0.0f);
    
    }
    
    
      cell.descriptionCell.frame =  CGRectMake(20.0f, 10.0f + cell.titleCell.frame.size.height, 270.0f, expectedDescriptionLabelSize.height+20.0f);
    
    cell.titleCell.text = newsTitle;
    cell.descriptionCell.text = descriptionsText;
    
    NSLog(@"indexpath.row %d :title %@ ",indexPath.row,newsTitle);
    
    NSLog(@"indexpath.row %d :description %@",indexPath.row,descriptionsText);
    
    return cell;
    
     }
    

    pragma mark - UITableViewDelegate

       - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
     {
    float totalHeight = 0.0f;
    
    UILabel *labelTitle;
    
    
    CGSize maximumLabelSize;
    
    
    if([UIDevice currentDevice].userInterfaceIdiom==UIUserInterfaceIdiomPad || [[[UIDevice currentDevice] model] isEqualToString:@"iPad Simulator"])
    {
        labelTitle = [[UILabel alloc]initWithFrame:CGRectMake(0.0f, 0.0f, 692.0f, 20.0f)];  // iPad
        maximumLabelSize = CGSizeMake(768.0f, 10000.0f);
    
    }
    else
    {
        labelTitle = [[UILabel alloc]initWithFrame:CGRectMake(0.0f, 0.0f, 270.0f, 20.0f)];
        maximumLabelSize = CGSizeMake(270.0f, 10000.0f);
    
    }
    
    
    
    labelTitle.font = [UIFont systemFontOfSize:12.0f];
    
    
    NSString *newsTitle;
    NSString *newsDescription;
    
      //  cell.titleCell.text = [[feeds objectAtIndex:indexPath.row] objectForKey: @"title"];
      //   cell.descriptionCell.text = [[feeds objectAtIndex:indexPath.row] objectForKey: @"description"];
    
    
    
        newsTitle = [[feeds objectAtIndex:indexPath.row] objectForKey: @"title"];
    
        newsDescription = [[feeds objectAtIndex:indexPath.row] objectForKey: @"description"];
    
    NSLog(@"indexpath.row %d :newsDescription.length %d",indexPath.row,newsDescription.length);
    CGSize expectedTitleLabelSize;
    CGSize expectedDescriptionLabelSize;
    
    
    if (newsTitle.length > 0)
    {
        expectedTitleLabelSize = [newsTitle sizeWithFont:labelTitle.font constrainedToSize:maximumLabelSize lineBreakMode:labelTitle.lineBreakMode];
        totalHeight = totalHeight + 20.0f;
    }
    else
    {
        expectedTitleLabelSize = CGSizeMake(0.0f, 0.0f);
        totalHeight = -20.0f;
    }
    
    if (newsDescription.length > 0)
    {
        expectedDescriptionLabelSize = [newsDescription sizeWithFont:labelTitle.font constrainedToSize:maximumLabelSize lineBreakMode:labelTitle.lineBreakMode];
        totalHeight = totalHeight + 20.0f;
    
    }
    else
    {
        expectedDescriptionLabelSize = CGSizeMake(0.0f, 0.0f);
        totalHeight = -20.0f;
    }
    
    
    //  NSLog(@"question: %f title:%f",expectedQuestionLabelSize.height,expectedTitleLabelSize.height);
    
    totalHeight = expectedDescriptionLabelSize.height + expectedTitleLabelSize.height + 30.0f+20.0f;
    
    
    
    
    return totalHeight;
    
     }
    
    0 讨论(0)
  • 2020-11-27 18:42

    To set automatic dimension for row height & estimated row height, ensure following steps to make, auto dimension effective for cell/row height layout.

    • Assign and implement tableview dataSource and delegate
    • Assign UITableViewAutomaticDimension to rowHeight & estimatedRowHeight
    • Implement delegate/dataSource methods (i.e. heightForRowAt and return a value UITableViewAutomaticDimension to it)

    -

    @IBOutlet weak var table: UITableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        // Don't forget to set dataSource and delegate for table
        table.dataSource = self
        table.delegate = self
    
        // Set automatic dimensions for row height
        // Swift 4.2 onwards
        table.rowHeight = UITableView.automaticDimension
        table.estimatedRowHeight = UITableView.automaticDimension
    
    
        // Swift 4.1 and below
        table.rowHeight = UITableViewAutomaticDimension
        table.estimatedRowHeight = UITableViewAutomaticDimension
    
    }
    
    
    
    // UITableViewAutomaticDimension calculates height of label contents/text
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        // Swift 4.2 onwards
        return UITableView.automaticDimension
    
        // Swift 4.1 and below
        return UITableViewAutomaticDimension
    }
    

    For label instance in UITableviewCell

    • Set number of lines = 0 (& line break mode = truncate tail)
    • Set all constraints (top, bottom, right left) with respect to its superview/ cell container.
    • Optional: Set minimum height for label, if you want minimum vertical area covered by label, even if there is no data.

    enter image description here

    0 讨论(0)
  • 2020-11-27 18:47

    Try This, It worked like a charm! for me,

    In viewDidLoad write this code,

    -(void)viewDidLoad 
    {
    [super viewDidLoad];
     self.tableView.estimatedRowHeight = 100.0; // for example. Set your average height
     self.tableView.rowHeight = UITableViewAutomaticDimension;
    }
    

    In cellForRowAtIndexPath write this code,

     -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
     {
      static NSString *CellIdentifier = @"Cell";
      UITableViewCell *cell = [tableView 
      dequeueReusableCellWithIdentifier:CellIdentifier];
     if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] ;
      }
        cell.textLabel.numberOfLines = 0; // Set label number of line to 0
        cell.textLabel.text=[[self.arForTable objectAtIndex:indexPath.row] valueForKey:@"menu"];
        [cell.textLabel sizeToFit]; //set size to fit 
        return cell;
     }
    

    Hopes so this will help for some one .

    0 讨论(0)
  • 2020-11-27 18:49

    Please, Look HERE - Dynamic Table View Cell Height and Auto Layout tutorial.

    What you need:

    • set required constraint on elements in cell (make shure that all done correctly, if no - you can get a lot of problem). Also make shure that you set IntrinsicSize to PlaceHolder value

    enter image description here

    • add few method for calculating size of cell

    Methods:

    //this will calculate required height for your cell
    -(CGFloat)heightForBasicCellAtIndexPath:(NSIndexPath *)indexPath {
          static UIYourClassCellName *sizingCell = nil;
          //create just once per programm launching
          static dispatch_once_t onceToken;
          dispatch_once(&onceToken, ^{
          sizingCell = [self.tableView dequeueReusableCellWithIdentifier:@"identifierOfCell"];
    });
      [self configureBasicCell:sizingCell atIndexPath:indexPath];
      return [self calculateHeightForConfiguredSizingCell:sizingCell];
    }
    //this method will calculate required height of cell
    - (CGFloat)calculateHeightForConfiguredSizingCell:(UITableViewCell *)sizingCell {
          [sizingCell setNeedsLayout];
          [sizingCell layoutIfNeeded];
          CGSize size = [sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
          return size.height;
    }
    

    And call

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
      return [self heightForBasicCellAtIndexPath:indexPath];
    }
    

    Configuration of cell

    - (void)configureBasicCell:(RWBasicCell *)cell atIndexPath:(NSIndexPath *)indexPath {
        //make some configuration for your cell
    }
    

    After all operation i got next (text inside cell only as placeholder):

    enter image description here

    0 讨论(0)
  • 2020-11-27 18:49

    If you want to constrain the maximum height to 100 pt you have to use MIN instead on MAX:

    CGFloat height = fmin(size.height, 100.0);
    
    0 讨论(0)
提交回复
热议问题