Reputation: 149
I am working on a UITableViewController
view that has a bunch of content in the UITableView
header of varying height. The height requirement of the entire header will vary, so I need to set it dynamically based on which content is displayed in there.
Below is what I have been trying after searching for potential solutions. The UITableView.automaticDimension
doesn't seem to be doing anything. Setting tableView.sectionHeaderHeight
to a static number works, but I can't quite get it to be set dynamically.
This is all being done programmatically.
Am I going about this the correct way? Basically after all the subviews have been added to the headerView I want to set the height of the entire header.
ViewDidLoad:
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self as! UITableViewDataSource
tableView.sectionHeaderHeight = UITableView.automaticDimension
tableView.estimatedSectionHeaderHeight = 200;
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
}
Supposed to be setting the header height?
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return UITableView.automaticDimension
}
override func tableView(_ tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat {
return 200
}
Adding the header content:
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let v = headerView
v.translatesAutoresizingMaskIntoConstraints = false
v.addSubview(headingLabel)
v.addSubview(subheadingLabel)
v.addSubview(additionalContent)
headerConstraints()
return v
}
This is what I'm kind of hoping to see:
Any suggestions?
Thanks!
Upvotes: 1
Views: 4831
Reputation: 7585
The problem is:
v.translatesAutoresizingMaskIntoConstraints = false
When you provide your custom view as a header/footer for the table view section, you don't need to modify the auto resizing mask on the returned view itself. To my best understanding, doing this breaks table view's internal setup.
But if you register a UITableViewHeaderFooterView
subclass as the header/footer, you have to consider that option as you are taking control of configuring the entire header/footer.
Now, I suppose your
let v = headerView
. . .
headerConstraints()
codes are correct. If that is so, the above change should work as expected.
Otherwise below is an example you can try:
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let v = UIView()
let headingLabel = UILabel(frame: .zero)
headingLabel.translatesAutoresizingMaskIntoConstraints = false
headingLabel.text = "View Header"
headingLabel.font = UIFont.systemFont(ofSize: 30, weight: .heavy)
headingLabel.textColor = .black
let subheadingLabel = UILabel(frame: .zero)
subheadingLabel.translatesAutoresizingMaskIntoConstraints = false
subheadingLabel.text = "Subheader Content"
subheadingLabel.font = UIFont.systemFont(ofSize: 15, weight: .semibold)
subheadingLabel.textColor = .gray
let additionalLabel = UILabel(frame: .zero)
additionalLabel.translatesAutoresizingMaskIntoConstraints = false
additionalLabel.text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
additionalLabel.numberOfLines = 0
additionalLabel.font = UIFont.systemFont(ofSize: 15, weight: .regular)
additionalLabel.textColor = .white
let additionalContent = UIView(frame: .zero)
additionalContent.translatesAutoresizingMaskIntoConstraints = false
additionalContent.backgroundColor = .black
additionalContent.addSubview(additionalLabel)
additionalLabel.leadingAnchor.constraint(equalTo: additionalContent.leadingAnchor, constant: 10).isActive = true
additionalLabel.trailingAnchor.constraint(equalTo: additionalContent.trailingAnchor, constant: -10).isActive = true
additionalLabel.topAnchor.constraint(equalTo: additionalContent.topAnchor, constant: 10).isActive = true
additionalContent.bottomAnchor.constraint(equalTo: additionalLabel.bottomAnchor, constant: 10).isActive = true
let stackView = UIStackView(frame: .zero)
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.alignment = .fill
stackView.distribution = .fill
stackView.spacing = 8
stackView.addArrangedSubview(headingLabel)
stackView.addArrangedSubview(subheadingLabel)
stackView.addArrangedSubview(additionalContent)
v.addSubview(stackView)
stackView.leadingAnchor.constraint(equalTo: v.leadingAnchor, constant: 16).isActive = true
stackView.trailingAnchor.constraint(equalTo: v.trailingAnchor, constant: -16).isActive = true
stackView.topAnchor.constraint(equalTo: v.topAnchor, constant: 16).isActive = true
stackView.bottomAnchor.constraint(equalTo: v.bottomAnchor, constant: -16).isActive = true
return v
}
And don't forget (if you need automatic height calculation):
override func viewDidLoad() {
super.viewDidLoad()
. . .
tableView.sectionHeaderHeight = UITableView.automaticDimension
tableView.estimatedSectionHeaderHeight = 100
. . .
}
Upvotes: 3
Reputation: 846
I believe this can be resolved if you set the clipsToBounds
of tableView to be true.
Using code:
tableView.clipsToBounds = true
Using interface builder:
Upvotes: 1