Our logic for modifying the navigation bar isn't working on devices running iOS 15.1 Beta or simulators running iOS 15.0 on Xcode 13. When scrolling, we want to change the position of the navigation bar so that it goes off screen to enable a so called fullscreen mode.
- Create a scroll view and implement UIScrollViewDelegate
- Inside scrollViewDidScroll, modify the Y-position of self.navigationController.navigationBar.frame
- Launch the app and scroll vertically
Expected: Navbar is moved off screen when you scroll down and comes back when you scroll up. Actual: Navbar stays in position at all times.
Workarounds: Use iOS 14 or below
Here are two video demonstrations of Expected VS Actual results:
iOS 14.5: https://www.dropbox.com/s/kplb13taioxrw7g/iOS14.5_scroll.mov?dl=0
iOS 15.0: https://www.dropbox.com/s/uyvy6oxcgi1wj8i/iOS15_scroll.mov?dl=0
Code:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if let navController = self.navigationController {
var navBarFrame = navController.navigationBar.frame
// Change y-position
let newYPosition = min(0, max(-(navbarHeight), (scrollView.contentOffset.y * -1))) + statusBarHeight
navBarFrame.origin.y = newYPosition
navController.navigationBar.frame = navBarFrame
NSLog("New Y positon: %f", newYPosition)
}
}
And here's the full demo project: https://github.com/karlingen/NavbarHideOnScroll
Is this a bug?
UINavigationController
owns the geometry of its own navigationBar
and attempts to modify that geometry from outside of UINavigationController
are not supported. This is a general rule, that a view's superview owns its geometry, and in the case of the UINavigationBar
vended by UINavigationController
that is the UINavigationController
's view, Since you have no access to that view to subclass (or otherwise modify its behavior) there is no means to modify the position of the navigationBar
without making assumptions that will change over time.