How can I do variable height table cells on the iPhone properly?

前端 未结 3 1896
时光取名叫无心
时光取名叫无心 2020-12-12 19:56

My app needs to have variable height table cells (as in each table cell differs in height, not that each cell needs to be able to resize itself).

I have a solution t

相关标签:
3条回答
  • 2020-12-12 20:19

    Just a thought:

    • What if you had, say, six different types of cells each with their own identifier and a fixed height. One would be for a single-line cell, the other for a two-line cell, etc...

    • Every time your model changes, calculate the height for that row then find the nearest cell type that has height closest to what you need. Save that celltype identifier with the model. You can also store the fixed row height for that cell in the model so you can return it in the tableview:heightForRowAtIndexPath call (I wouldn't get too hung up on forcing it to calculate inside the cell class itself--technically it's not part of the cell drawing functionality and more something the tableview uses to decide which cell type to create).

    • At runtime, when asked to return a cell for that row all you need to do is create (or obtain from the cell cache) a cell with the celltype identifier, load the values and you're good to go.

    If the cell height calculation is too slow, then you could pull the same trick the tableview cache does and do it only on-demand when the cell comes into view. At any given time, you would only have to do it for the cells in view, and then only for a single cell as it scrolls into view at either end.

    0 讨论(0)
  • 2020-12-12 20:21

    I realise this won't work for you due to the infinite loop you mention, but I've had some success with calling the cells layoutSubViews method

    Though this may be a little inefficient due to multiple calls to both cellForRowAtIndexPath and layoutSubViews, I find the code is cleaner.

    -(float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        MyCell *cell = (MyCell *)[self tableView:tableView cellForRowAtIndexPath:indexPath];
    
        [cell layoutSubviews];
    
        return CGRectGetHeight(cell.frame);
    }
    

    And in the layout code:

    - (void)layoutSubviews
    {
        [super layoutSubviews];
    
        //First expand the label to a large height to so sizeToFit isn't constrained
        [self.myArbitrarilyLengthLabel setFrame:CGRectMake(self.myArbitrarilyLengthLabel.frame.origin.x,
                                              self.myArbitrarilyLengthLabel.frame.origin.y,
                                              self.myArbitrarilyLengthLabel.frame.size.width,
                                              1000)];
    
    
        //let sizeToFit do its magic
        [self.myArbitrarilyLengthLabel sizeToFit];
    
        //resize the cell to encompass the newly expanded label
        [self setFrame:CGRectMake(self.frame.origin.x,
                                 self.frame.origin.y,
                                 self.frame.size.width,
                                  CGRectGetMaxY(self.myArbitrarilyLengthLabel.frame) + 10)];
    }
    
    0 讨论(0)
  • 2020-12-12 20:34

    Here's what I use. NSString has a method that will tell you the dimensions of a textbox based on the font information and the height/width constraints you give it.

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        NSString *text = [self getTextForIndexPath:indexPath];
        UIFont *font = [UIFont systemFontOfSize:14];
        CGSize size = [self getSizeOfText:text withFont:font];
    
        return (size.height + 11); // I put some padding on it.
    }
    

    Then you write a method pull the text for this cell...

    - (NSString *)getTextForIndexPath:(NSIndexPath *)indexPath
    {
        NSString *sectionHeader = [self.tableSections objectAtIndex:[indexPath section]];
        NSString *sectionContent = [self.tableData objectForKey:sectionHeader];
    
        return sectionContent;
    }
    

    And this is to get the size of the text.

    - (CGSize)getSizeOfText:(NSString *)text withFont:(UIFont *)font
    {
        return [text sizeWithFont:font constrainedToSize:CGSizeMake(280, 500)];
    }
    
    0 讨论(0)
提交回复
热议问题