Problem
A navigation bar animates as it hides on scroll (hidesBarsOnSwipe
). If there is a table on the page with a section header, the section header will stick to the top of the view and follow the user as they scroll. When using these two together, there is a gap between the section header and the navigation bar when the navigation bar is hiding, showing the background table cells. I would expect the section header to follow the navigation bar as it hides without a gap.
Using a section header is not strictly necessary for my issue. I'd simply like a bar that sticks to the top of the screen and follows the user as they scroll.
I've tried alternative approaches to the example posted below, which uses a UITableViewController
. Adjusting the insets causes the section header to slip under the status bar. Using a UIViewController
containing a static UIView
(for the section header) and UITableView
causes the same issue.
What would be an appropriate solution for this issue?
Example
The status bar's background is gray and the section header's background is red to better highlight the gap between the navigation bar and the section header. As the table is slowly scrolled down, the yellow table cells peeking through the gap become apparent. After the navigation bar is hidden, the section header resets on the status bar as expected.
View controller used for the above animation:
class TableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Color status bar background.
let statusBar: UIView = UIApplication.shared.value(forKey: "statusBar") as! UIView
if statusBar.responds(to: #selector(setter: UIView.backgroundColor)) {
statusBar.backgroundColor = .lightGray
}
UIApplication.shared.statusBarStyle = .default
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 20
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
return tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)
}
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let view = UIView()
view.backgroundColor = .red
return view
}
}
Update 1
Removing the background color from the status bar does not resolve the issue I am seeing. The GIF below shows the behavior with the status bar in its original, transparent state.
TLYShyNavBar has a GIF of the behavior I’d like to implement (added below). This project is not maintained and does not work without additional manipulation but has a good example of what I would expect the behavior to look like.
Update 2
I’m understanding that this behavior is not an error/issue but as Apple prefers it. Coloring the background of the View is an option (see answer below). There are two ways to go about that for this situation:
Color the background to match the navigation bar and remove the navigation bar’s shadow to make the view seamless.
self.navigationController?.navigationBar.shadowImage = UIImage() self.navigationController?.navigationBar.isTranslucent = false
Color the background to match the red bar.
Unfortunately, this method masks the gap instead of removing it. It makes one of the bars appear to distort in shape during their animation until they've completed their transition in both cases.