I am currently using a UIViewController
and adding a UITableView
to the view. With this tableView
I am adding a UIView
called containerView
to its tableHeaderView
. I set the height of the container view and then adding a second UIView
to its subview, that is pinned to the bottom of the containerView
.
When I add it to the header view the cells are being overlapped. What's odd though is that if I don't add the subview to the container view the headerView
is not being overlapped by the cells, it is only occurring when I am adding the second view as a subview to the container view.
class ViewController: UIViewController {
private var containerView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.alpha = 0.7
view.backgroundColor = .red
return view
}()
private var bottomView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = .blue
return view
}()
private(set) lazy var tableView: UITableView = {
let tableView = UITableView()
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.dataSource = self
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
return tableView
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(tableView)
containerView.addSubview(bottomView)
tableView.tableHeaderView = containerView
NSLayoutConstraint.activate([
tableView.topAnchor.constraint(equalTo: view.topAnchor),
tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
containerView.topAnchor.constraint(equalTo: tableView.topAnchor),
containerView.heightAnchor.constraint(equalToConstant: 214),
containerView.widthAnchor.constraint(equalToConstant: view.frame.size.width),
bottomView.topAnchor.constraint(equalTo: containerView.bottomAnchor),
bottomView.heightAnchor.constraint(equalToConstant: 114),
bottomView.widthAnchor.constraint(equalToConstant: view.frame.size.width),
])
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
tableView.contentInset = UIEdgeInsets(top: -view.safeAreaInsets.top, left: 0, bottom: 0, right: 0)
tableView.tableHeaderView?.autoresizingMask = []
tableView.tableHeaderView?.layoutIfNeeded()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
}
}
The reason your "blue view" is overlapping the cells is because you are constraining its Top to the red view's Bottom, but you're not updating the header view size.
One good approach is to create a
UIView
subclass to use as your header view. Setup all of its content with proper auto-layout constraints.Then, in the controller's
viewDidLayoutSubviews()
, we use.systemLayoutSizeFitting(...)
to determine the header view's height and update its frame:Here is a complete example...
First, our custom view class:
and a sample controller:
Output:
and rotated: