Reputation: 933
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:
These are my constraints (static cell with the contentView of the container View):
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
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
Reputation: 1153
So if I correctly understand you actually have those constraints :
Basically what you want is this constraint :
If it's the case you can try to put a constraint to fix a minimum of height for the containerView like this :
Then you can try to put an optional constraint for the equal height :
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