I am currently working on a project where I have embedded a UITableView
inside UITableViewCell
.
What I need to do is to disable the UITableView
's scroll and make the UITableView
to fit size of all rows. But as the UITableView
inherits from UIScrollView
, the use of Autolayout does not force UITableView
to make the height of cell depending on its contentSize (not frame) when returning UITableViewAutomaticDimension
.
iOS 7 Solution
This was easy achievable until iOS 7, as I get the reference of the cell under heightForRowAtIndexPath:
using the code below:
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
int height = cell.tableView.contentSize.height;
return height;
but in iOS 8 it gives BAD_ACCESS as iOS 8 calls the heightForRowAtIndexPath:
before the cellForRowAtIndexPath:
has been called.
iOS 8 Approach
Declare a property to keep reference of the cell:
@property (strong, nonatomic) UITableViewCell *prototypeCell
Use a method to save the current cell reference to the property in order to use it:
- (id)prototypeCellatIndexPath:(NSIndexPath *)indexPath {
NSString *cellID = @"MyCell";
if (!_prototypeCell) {
_prototypeCell = [self.tableView dequeueReusableCellWithIdentifier:cellID];
}
return _prototypeCell;
}
Get UITableView
of the UITableViewCell
from the prototype and from its contentSize I get the height and I return it under heighForRowAtIndexPath:
from the method below:
-(int)heightForThreadAtIndexPath:(NSIndexPath *)indexPath {
_prototypeCell = [self prototypeCellatIndexPath:indexPath];
[_prototypeCell.contentView setNeedsLayout];
[_prototypeCell.contentView layoutIfNeeded];
int footer = [_prototypeCell.tableView numberOfSections]*_prototypeCell.tableView.sectionFooterHeight;
int header = [_prototypeCell.tableView numberOfSections]*_prototypeCell.tableView.sectionHeaderHeight;
int height = ceilf(_prototypeCell.tableView.contentSize.height) + _prototypeCell.tableView.contentOffset.y + _prototypeCell.tableView.contentInset.bottom + _prototypeCell.tableView.contentInset.top + header + footer;
NSLog(@"%i, %i", (int)ceilf(_prototypeCell.tableView.contentSize.height), height);
return height;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return [self heightForThreadAtIndexPath:indexPath];
}
Problem
The contentSize.height that I get back from the prototypeCell is wrong, and it doesn't match the real contentSize of the UITableView
, but when I log the real contentSize under CustomCell Class it shows the correct contentSize, which differs from the one under prototypeCell.
This makes me wondering that maybe I should try to dequeue the cell at a specific state in order to get the correct contentSize, but logs shows the same values.
I have been researching a lot and trying different ideas, but none worked so far. I don't know if anyone has tried to achieve a similar thing as me, and solved this. It will be really nice if you provide me an idea or something.