neteot
neteot

Reputation: 933

Dynamic height on a static cell with containerView embedded

I want to achieve a desire behaviour using autolayout (or if this is not possible using a delegate or something). What I have is a tableView with one static cell, this cell has a containerView that have a tableViewController with dynamic prototype cells.

What I want is be able to use autolayout to dynamically set the height of the static cell that has the container view embedded.

This is the storyboard:

enter image description here

These are my constraints (static cell with the contentView of the container View):

enter image description here

In the viewController that have the containerView within the static cell what I have is on the ViewDidLoad method:

override func viewDidLoad() {
    super.viewDidLoad()

    courseDetailTableView.estimatedRowHeight = 200
    courseDetailTableView.rowHeight = UITableViewAutomaticDimension
}

And using the delegate of the tableView with the staticCell:

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

But with this the height of the static cell is really small... it means that the autolayout is not capable of setting the height of his content with only the constraints that I have set.. I said only the constraints because if I set one more constraint on the contentView of the containerView that set the height to something like 400 then the height of that cell is 400..

I was just wondering if there is a way with autolayout to set the height of the static cell to match the height of the containerView.

I know that maybe using a delegate that calculates first the height of the containerView and use this height to set the heightForRow at it could possible work I want to know if there is a simpler way

Thank you so much.

Upvotes: 0

Views: 1021

Answers (2)

neteot
neteot

Reputation: 933

I just want to answer my own question just for someone facing maybe the same problem. It doesn't have to be with static cell, this answer applies to static as well as dynamic cells.

What you have to do is in the containerViewController set a property or a method for calculating the height (don't forget to ask for layoutIfNeeded)

func tableViewHeight() -> CGFloat {
    tableView.layoutIfNeeded()
    return tableView.contentSize.height
}

Then in the master view controller (the one that have the cell in which is the containerViewController embedded) you have to save a reference to the containerViewController for example in the prepare for segue method like so:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "containerSegue" {
        guard let containerVC = segue.destination as? SessionCoordinatorController else { return }
        sessionController = containerVC
    }
}

Then just ask for the container height in the delegate method of UITableView heightForRowAt like so (in the masterViewController):

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    guard let height = sessionController?.tableViewHeight() else { return UITableViewAutomaticDimension }
    return height
}

And that's it

Don't forget to add the tableView.isScrollEnabled to false in the containerViewController

Upvotes: 2

Arrabidas92
Arrabidas92

Reputation: 1153

So if I correctly understand you actually have those constraints :

  • ContentView.bottom = ContainerView.bottom
  • ContentView.trailing = ContainerView.trailing + Standard
  • ContainerView.leading = ContentView.leading + Standard
  • ContainerView.top = ContentView.top

Basically what you want is this constraint :

  • ContentView.height = ContainerView.height right ? But if you put it you have a very small cell ?

If it's the case you can try to put a constraint to fix a minimum of height for the containerView like this :

  • ContainerView.height >= 400 // At least 400 for the height for example

Then you can try to put an optional constraint for the equal height :

  • ContentView.height = ContainerView.height (priority 249 or low)

By lowering the priority of the constraint you are saying "I have this extra constraint, it will be great if the contentView matches the containerView height if not keep going or approximate to it".

Here is more info about AutoLayout AutooLayout Understanding

P.S : You don't need to implement tableView:heightForRowAtIndexPath: delegate method by returning automaticDimension.

Upvotes: 0

Related Questions