Reputation: 10329
When I push, using storyboard segue, to the next view, it loads a space for the statusbar, even though the next view has set the prefersStatusBarHidden
to false
.
I have also tried by subclassing the UINavigationController
and setting prefersStatusBarHidden
to false
in there, but still the view loads a space for it. Also automaticallyAdjustsScrollViewInsets
is set to false
.
The view that is loaded consist of an UIViewController
which has a UITableView
. The background color of the UIViewController
is (for testing) set to orange and the one for the table view is set to Pink. Neither of these colours are shown.
After som testing, it seems to me that the UINavigationController
adds a space for its root view and removes that space after animating the push. If I set the background color of the UINavigationController
to purple, I get the following result:
This shows that the view it is pushing to is neither renedered nor in the correct Y position. I can't seem to find why this is.
My UINavigationController
is contained in an UIViewController
which has a container for the view (rootViewController
).
The navigation controller is create programatically whenever a root-page is requested to be loaded. This is that code:
/// Load a view controller with UINavigationController into the
/// rootViewController and display it
///
/// - Parameter viewController: The view controller to show
func loadViewControllerPage(_ viewController: UIViewController) {
let nav = UINavigationController(rootViewController: viewController)
// No bar, please
nav.isNavigationBarHidden = true
// Make the view get in there propperly
nav.willMove(toParentViewController: self)
addChildViewController(nav)
nav.view.willMove(toSuperview: rootViewController)
nav.view.frame = rootViewController.bounds
rootViewController.addSubview(nav.view)
nav.view.didMoveToSuperview()
nav.didMove(toParentViewController: self)
rootViewController.bringSubview(toFront: nav.view)
/* Test if this fixes the statusbar issue
nav.edgesForExtendedLayout = .all
nav.automaticallyAdjustsScrollViewInsets = false
nav.extendedLayoutIncludesOpaqueBars = false
*/
currentNav = nav
// Cleanup
for child in childViewControllers {
if let c = child as? UINavigationController, c != nav && c.view.isDescendant(of: rootViewController) && c != menuView {
c.removeFromParentViewController()
c.view.removeFromSuperview()
}
}
}
Any suggestions on how I can solve this?
Upvotes: 2
Views: 1530
Reputation: 48514
didMoveToSuperview()
programmatically is a sure sign that the design is likely flawed, or unnecessarily convoluted at bestloadViewControllerPage
to push views onto a navigation controller or replace the root view controllerNotice how the status bar, visible on the orange view, isn't on the blue one. See animation.
When I push, using storyboard segue, to the next view, it loads a space for the statusbar, even though the next view has set the
prefersStatusBarHidden
to false.
To hide the status bar in your second view controller, set prefersStatusBarHidden
to true
, not false.
override var prefersStatusBarHidden:Bool {
return true
}
If you do not want to display the navigation bar, change the Bar Visibility in the Navigation Controller Attributes Inspector.
No code required for this. If you positively must use segues programmatically, see this StackOverflow answer.
No need to go through this path. Use a Storyboard ID to find and load the navigation controller from the storyboard.
Why so much code around loadViewControllerPage
, and why subclassing UINavigationController
?
If the object of your custom UIViewController
loading is the animation, see this StackOverflow post.
Navigation Controller visibility, status bar visibility, segues, all defined by resources and yielding very little to no code.
Upvotes: 3