0

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.

neteot
  • 933
  • 1
  • 12
  • 33
  • Why don't you use UITableViewController instead of all this mess with static cell what contain ContainerView, what contain UITableViewController with dynamic cells? – Taras Chernyshenko Oct 02 '17 at 11:18
  • Hi @TarasChernyshenko I know it seems a little confusing to have all this thing wrapping in here.. but this is because I need it for a later version which has two tableview one next to other and one controller. Now it doesnt make any sense but later it will be more easy this way (at least I think so) – neteot Oct 02 '17 at 14:06

2 Answers2

2

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

neteot
  • 933
  • 1
  • 12
  • 33
  • what if we don't have a table view in the master vc? dragged and dropped a container vc and embedded to a tableVC, how to set the height of the containerview in the master – Hatim Mar 21 '20 at 01:50
0

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.

Arrabidas92
  • 1,113
  • 1
  • 9
  • 20
  • What I need is that the static cell to increase to fit the height of the containerView embedded in (the containerView is a UITableViewController). I want to accomplish this using auto-layout, if I set the height manually (by putting a heigh constraint the it works) but I don't want this because I don't know what height the contentView is going to have... it depends on how many cells it has – neteot Oct 02 '17 at 14:29
  • So, did you try those constraints : 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) – Arrabidas92 Oct 02 '17 at 14:40
  • Hi @Arrabidas92 thank you but the proposed solution is not working. https://imgur.com/a/Ijg50 I think because the height is never more than 400 (even that is actually is) because I think a UITableView height is the same as UIScrollView height that is 0. I think I have to go with another approach :/ – neteot Oct 03 '17 at 06:50