user5730871
user5730871

Reputation:

UITableView ContentSize when using dynamic height on UITableViewCells

I've been searching for this for many hours but didn't find a way to make it.

I have a UITableView whose UITableViewCells use AutomaticDimension for Height:

tableView.RowHeight = UITableView.AutomaticDimension;
tableView.EstimatedRowHeight = 160f;

The problem is when I try to get tableView's ContentSize. It seems to be calculated based on EstimatedRowHeight instead of the current height of its rows. Suppose, if there are 10 Cells then ContentSize's returned value is 160x10.

Then my question is if there is a way to do this.

Any help will be really appreciated... I use Xamarin.iOS but Obj-C and Swift answers are obviously welcome :)

Upvotes: 8

Views: 12693

Answers (4)

JIIN
JIIN

Reputation: 1

tableView.reloadData()
view.layoutIfNeeded()
tableViewHeightConstraint.constant = tableView.contentSize.height
view.layoutIfNeeded()

Before getting tablaview.contentSize.height
reload tableView
You need to update the view.

Upvotes: 0

Artur Guseynov
Artur Guseynov

Reputation: 93

self.coins = coins
tableView.reloadData()
view.layoutIfNeeded()
tableViewHeightConstraint.constant = tableView.contentSize.height
view.layoutIfNeeded()

worked without UITableViewAutomaticDimension and estimatedRowHeight. iOS 11

Upvotes: 1

Echelon
Echelon

Reputation: 7922

I think @Daniel J's answer only works because of the way the animation completion handler is scheduled - on the face of it, there is no guarantee the table reload will have happened before the animation completes.

I think a better solution is (in Swift, as that is what I was using):-

func reloadAndResizeTable() {

    self.tableView.reloadData()
    dispatch_async(dispatch_get_main_queue()) {
        self.tableHeightConstraint.constant = self.tableView.contentSize.height
        UIView.animateWithDuration(0.4) {
            self.view.layoutIfNeeded()
        }
    }
}

I actually used the animation delay because of the effect I wanted, but it does also work with a duration of zero. I call this function every time I update the table contents and it animates in and resizes as necessary.

Upvotes: 13

Daniel J
Daniel J

Reputation: 446

I had a scenario where I needed to know the contentSize as well, to set the frame on a non-fullscreen tableView that had varying cell counts of varying heights. Then I'd adjust the tableView (via NSLayoutConstraint) to be the height of that content.

The following worked, though I feel it's a bit hacky:

Setup all code in 'viewDidLoad'
Set the rowHeight to automatic
Set the estimatedRowHeight to larger than I expected a cell to ever be (in this case, I didn't expect a cell to ever be taller than about 60pts, so set the estimated to 120)
Wrap the tableView reload in an animation block, and then query the contentSize and take appropriate action in the completion block

- (void)viewDidLoad {
    [super viewDidLoad]; 

    self.tableView.rowHeight = UITableViewAutomaticDimension;
    self.tableView.estimatedRowHeight = 120.0;

    [UIView animateWithDuration:0 animations:^{
        [self.tableView reloadData];
    } completion:^(BOOL finished) {
        self.tableViewHeight.constant = self.tableView.contentSize.height;
        [self.view layoutIfNeeded];
    }];
}

Upvotes: 7

Related Questions