Since I discovered AutoLayout
I use it everywhere, now I\'m trying to use it with a tableHeaderView
.
I made a subclass
of
I was able to achieve it by the following approach (this works for footer the same way).
First, you will need small UITableView
extension:
Swift 3
extension UITableView {
fileprivate func adjustHeaderHeight() {
if let header = self.tableHeaderView {
adjustFrame(header)
}
}
private func adjustFrame(_ view: UIView) {
view.frame.size.height = calculatedViewHeight(view)
}
fileprivate func calculatedHeightForHeader() -> CGFloat {
if let header = self.tableHeaderView {
return calculatedViewHeight(header)
}
return 0.0
}
private func calculatedViewHeight(_ view: UIView) -> CGFloat {
view.setNeedsLayout()
let height = view.systemLayoutSizeFitting(UILayoutFittingCompressedSize).height
return height
}
}
In your view controller class implementation:
// this is a UIView subclass with autolayout
private var headerView = MyHeaderView()
override func loadView() {
super.loadView()
// ...
self.tableView.tableHeaderView = headerView
self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension
// ...
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
// this is to prevent recursive layout calls
let requiredHeaderHeight = self.tableView.calculatedHeightForHeader()
if self.headerView.frame.height != requiredHeaderHeight {
self.tableView.adjustHeaderHeight()
}
}
Notes about a header UIView
's subview implementation:
You have to 100% sure that your header view has the correct autolayout setup. I would recommend to start with simple header view with just one heigh constraint and try out the setup above.
Override requiresConstraintBasedLayout
and return true
:
.
class MyHeaderView: UIView {
// ...
override static var requiresConstraintBasedLayout : Bool {
return true
}
// ...
}