2
votes

I have an application that uses tableviews on every screen. I have plenty of custom cells, each having different height. Right now calculating the height is quite a challenge. I am looking for a generic method that will return the height for each custom cell without using heightForRowAtIndex. The reason I don't want to use heightForRowAtIndex because I have 4 xibs behind one cell and I don't want to mess this metho with if ( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad ) {} kind of checks. For the record cell xibs are both iPhone, iPad with english and arabic versions:
cell_en.xib
cell_en~ipad.xib
cell_ar.xib
cell_ar~ipad.xib

Currently, I am trying following;

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

                case 0:
                {
                    VPCell1 *cell=[VPCell1 cellForTable:tableView withOwner:self];
                    [tableView setRowHeight:CGRectGetHeight(cell.contentView.frame)];
                    return cell;
                }
                case 1:
                {
                    VPCell2 *cell=[VPCell2 cellForTable:tableView withOwner:self];
                    [tableView setRowHeight:CGRectGetHeight(cell.contentView.frame)];
                    return cell;
                }
                case 2:
                {
                    VPCell3 *cell=[VPCell3 cellForTable:tableView withOwner:self];
                    [tableView setRowHeight:CGRectGetHeight(cell.contentView.frame)];
                    return cell;
                }
          }
    }

Here I am using [tableView setRowHeight:CGRectGetHeight(cell.contentView.frame)]; to set row height for each cell.
Turns out setRowHeight method should be used, iff all cells inside a tableview have same height so definitely not a choice here for performance optimization. I am open to ideas to solve this mess.
Thanks!

3
Huh? You need to use heightForRowAtIndexPath to set the row height.Lyndsey Scott
Ahan, I am using a custom cell on for instance 20 screens. Let's say I have to change the xib file in terms of height, so you are suggesting that for this change I should change the cell height inside each tableviewcontroller. Its a painful approach to adopt, isn't it?Khawaja Farooq

3 Answers

1
votes

If all the cells of a tableview have the same height, then you set the tableview rowHeight, but only once when the tableview is loaded, let's say in the controller viewDidLoad.

If you have cells of different heights in the same tableView, then you have to use heightForRowAtIndexPath. And no, it's not painful, it's just the way it was designed.

0
votes

With iOS8, you can use AutoLayout and let UITableView calculate the rowheight. To tell UITableView about self-estimation of row-heights, you have to write these lines in viewDidLoad:

self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 50.0; // your estimated average cell height

And in your custom cells you have to override the method "layoutSubviews":

- (void)layoutSubviews
{
    [super layoutSubviews];

    // Make sure the contentView does a layout pass here so that its subviews have their frames set, which we
    // need to use to set the preferredMaxLayoutWidth below.
    [self.contentView setNeedsLayout];
    [self.contentView layoutIfNeeded];


    self.details.preferredMaxLayoutWidth = CGRectGetWidth(self.details.frame);
}

The approach described above is based on Custom Cells having all elements placed in the content view. Also all elements should be managed with Constraints.

Checkout my Example Project at github.

0
votes

UITableView.AutomaticDimension alone did not work for me.

I also had to apply

uiDescription.SetContentCompressionResistancePriority(1000, UILayoutConstraintAxis.Vertical);

to elements where i was expecting a view to expand its content