I\'m using a UITableView
to layout content \'pages\'. I\'m using the headers of the table view to layout certain images etc. and I\'d prefer it if they didn\'t
A variation on @samvermette's solution:
/// Allows for disabling scrolling headers in plain-styled tableviews
extension UITableView {
static let shouldScrollSectionHeadersDummyViewHeight = CGFloat(40)
var shouldScrollSectionHeaders: Bool {
set {
if newValue {
tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: bounds.size.width, height: UITableView.shouldScrollSectionHeadersDummyViewHeight))
contentInset = UIEdgeInsets(top: -UITableView.shouldScrollSectionHeadersDummyViewHeight, left: 0, bottom: 0, right: 0)
} else {
tableHeaderView = nil
contentInset = .zero
}
}
get {
return tableHeaderView != nil && contentInset.top == UITableView.shouldScrollSectionHeadersDummyViewHeight
}
}
}
I have another even simpler solution, to be used without autolayout and with everything done through the XIB :
1/ Put your header in the tableview by drag and dropping it directly on the tableview.
2/ In the Size Inspector of the newly made header, just change its autosizing : you should only leave the top, left and right anchors, plus the fill horizontally.
That should do the trick !
Although this may not solve your problem, it did for me when I wanted to do a similar thing. Instead of setting the header I used the footer of the section above. What saved me was that this section was small and static in nature, so it never scrolled below the bottom of the view.
Maybe you could use scrollViewDidScroll
on the tableView
and change the contentInset
based on the current visible header.
It seems to work for my use case!
extension ViewController : UIScrollViewDelegate{
func scrollViewDidScroll(_ scrollView: UIScrollView) {
guard let tableView = scrollView as? UITableView,
let visible = tableView.indexPathsForVisibleRows,
let first = visible.first else {
return
}
let headerHeight = tableView.rectForHeader(inSection: first.section).size.height
let offset = max(min(0, -tableView.contentOffset.y), -headerHeight)
self.tableView.contentInset = UIEdgeInsetsMake(offset, 0, -offset, 0)
}
}
Check the answer how to implement headers with StoryBoard: Table Header Views in StoryBoards
Also notice that if you don't implement
viewForHeaderInSection:(NSInteger)section
it will not float which is exactly what you want.
For Swift 3+
Simply use UITableViewStyleGrouped
and set the footer's height to zero with the following:
override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return .leastNormalMagnitude
}