I am hiding my navigation bar when I scroll by calling: self.navigationController?.setNavigationBarHidden(true, animated: true)
The only problem is that the navbar doesnt get hidden all the way.
Whats even stranger is if I push to a new VC and go back and now try to scroll the navigation bar gets hidden all the way which is what I want.
If it matters I am hiding the navigation bar on VC2 then showing it when I exit back to VC 1.
This is what it looks when I try to hide the navbar first time, it doesnt go up all the way/underlying view showing too much.
If I push the to next VC and go back and now try to hide the navigationbar it works
The my view has a constraint of 0 to top layout so its hugging the top
So how can I make my view always be like in the second image when hiding my navigation bar?
Try this code...
Note: This is a simple approach for your problem. If you want more custom look navBar and status bar look .You should read my previous comment...
Set navigation controller property hidesBarsOnSwipe to true
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
navigationController?.hidesBarsOnSwipe = true
}
I understand your question.
The green part in your second image is not a navigation bar, it is a status bar.
You can hide the status bar as below.
You should implement prefersStatusBarHidden on your view controller(s):
In Swift 2:
override func prefersStatusBarHidden() -> Bool {
return true
}
In Swift 3:
override var prefersStatusBarHidden: Bool {
return true
}
Related
I have view controller which navigation bar is hidden.
navigationController?.isNavigationBarHidden = true
I push another controller when tap on a button.
navigationController?.pushViewController(qrGenerateVC, animated: true)
In the second view controller the navigation bar is not hidden.
In other situations when I swipe back the second navigation bar hides smoothly but in this situation It disappear when I start swiping back. so it makes the view look not good.
This is similar to this question which does not have answer. And the view is similar too.
Before swipe screenShot
After swipe screenShot
These images are from that question. but similar thing happens here.
Set this in your second view controller
override func viewWillAppear(_ animated: Bool) {
self.navigationController?.isNavigationBarHidden = false
}
I added a scroll view to my view which is hover the status bar (I hid it). The scroll view is working fine, but when I'm scrolling to the top, I have a white space which disappears when I tap on my screen, and appears again when I scroll down then top.
I noticed that the scroll bar is not going to the top of my view, but stopped at the status bar.
Here are screenshots which show you what I mean.
Here I'm at the top of my view but the scroll bar isn't:
Here is the same view with the white status bar which appears when I scroll top again:
It disappear when I tap on my screen or scroll down.
Here are my constraints:
I think it's a problem of Layout Margin or something like that, but I don't what I should change?
I hide the status bar like that in my view controller:
override func viewWillAppear(_ animated: Bool) {
UIApplication.shared.keyWindow?.windowLevel = UIWindowLevelStatusBar
super.viewWillAppear(animated)
}
EDIT: Even if I comment the line which hides the status bar, I still have the same problem with my scroll view. So the problem doesn't come from how I hide it.
As Sam said, I changed the content insets to "Never" on the scroll view and it works.
While unrelated to your question, I have to react to the way you hide the status bar - the proper way is to override prefersStatusBarHidden in your view controller and call self.setNeedsStatusBarAppearanceUpdate() in your viewWillAppear:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.setNeedsStatusBarAppearanceUpdate()
}
override var prefersStatusBarHidden: Bool {
return true
}
UPDATE
Since your view controller is inside of a UINavigationViewController, you need to override childViewControllerForStatusBarHidden in UINavigationViewController to use visibleViewController as the controller to determine status bar hidden (I added override to childViewControllerForStatusBarStyle for the consistence):
extension UINavigationController {
open override var childViewControllerForStatusBarStyle: UIViewController? {
return visibleViewController
}
open override var childViewControllerForStatusBarHidden: UIViewController? {
return visibleViewController
}
}
I have two viewcontrollers. The first viewcontroller is collection view controller and i set self.navigationController?.hidesBarsOnSwipe = true in viewDidLoad().
When I push the second viewController from the visible cell of collectionView, the navigation bar is showing in the second viewController but if I scroll the collectionView cell and when push the navigation is not showing.
Can anyone tell me what the problem is?
scrolling is done via swipe gesture, so it triggers your code:
self.navigationController?.hidesBarsOnSwipe = true
because navigation controller is shared between all view controllers presented on top of it, it's properties (like hidden bar) preserves pushing / popping.
Common pattern is to change it's state in overrided lifecycle methods, eg:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.hidesBarsOnSwipe = false
self.navigationController?.setNavigationBarHidden(false, animated: true)
}
and reverting those state in viewWillDisappear
When this property is set to true, an upward swipe hides the navigation bar and toolbar. A downward swipe shows both bars again. If the toolbar does not have any items, it remains visible even after a swipe. The default value of this property is false. (get it from apple)
See the doc https://developer.apple.com/documentation/uikit/uinavigationcontroller/1621883-hidesbarsonswipe
It means when you swipe up it will hide and when swipe down it will shown. That's the reason.
To fix it you can add following code to the other controller
[self.navigationController setNavigationBarHidden:NO animated:YES];
Don't get much insight what exactly you implemented, but try to unhide navigation bar in second view controller.
Add below code in viewDidLoad method of second View controller.
self.navigationController?.isNavigationBarHidden = false
Put this self.navigationController?.hidesBarsOnSwipe = false and this self.navigationController?.setNavigationBarHidden(false, animated: true) in your second view controller.
You might want to move your self.navigationController?.hidesBarsOnSwipe = true from viewDidLoad to viewWillAppear in your first view controller.
I have created a parallax detail view in swift. Wish to allow nav bar colour and title display when user scrolls down.
Like this example here on the detail view. This is in objective C and I can't figure out the swift version. I'm sure it's simple enough with a few lines of code in the right place.
https://github.com/KMindeguia/movies/blob/master/README.md
I know the nav bar has a .hideswhenuserswips function but can't find anything for this!
Thanks
If you use storyboard for your UINavigationController, you can set like this
Or, you can set in your code like this:
myNavigationController.hidesBarsOnSwipe = true
You can use scrollview delegate methods to show or hide navigation bar.
you can implement scrollViewDidScroll , scrollViewDidEndDecelerating or scrollViewWillBeginDecelerating.
from this delegate methods you can manage your navigation bar.
This component just using simple UIView and implementing UIScrollViewDelegate methods. You can add your custom view in top of parent view and hide it, implement UIScrollViewDelegate methods and track some contentOffset of uiscrollview. Like in this component from lines 237
scrollDelegate methods
Set the NavigationBar in each viewcontroller, if you would not show navigationbar use this code,
self.navigationController?.navigationBarHidden = true
And show the navigationbar in particular viewController put this below code,
self.navigationController?.navigationBarHidden = false
this lines used your method, or you use this code,
override func viewWillAppear(animated: Bool)
{
super.viewWillAppear(animated)
self.navigationController?.navigationBarHidden = true
}
override func viewWillDisappear(animated: Bool)
{
super.viewWillDisappear(animated)
self.navigationController?.navigationBarHidden = false
}
when scrolling to show your navigationbar see this link Hide status bar while scrolling
hope its helpful
I have the hidesBottomBarWhenPushed = true set for one of my UIViewController's (call it ViewControllerA) that is pushed onto my UINavigationController stack. I also opt to show the bottomBar when I push a new ViewController ontop of ViewControllerA. Therefore I have:
class ViewControllerA: UIViewController {
override func viewWillDisappear(animated: Bool) {
self.hidesBottomBarWhenPushed = false
}
override func viewWillAppear(animated: Bool) {
self.hidesBottomBarWhenPushed = true
}
This all works fine.
When I push ViewControllerA, the bottom bar hides.
When I push any other ViewController, the bottom bar shows.
However, when I am traveling backwards in the navigation stack (aka hitting the UIBarButtonItemBack button), I cannot get the bottomBar to hide when I pop the navigation stack to reveal ViewControllerA.
What am I missing? Thanks!
Got it! Here's what worked:
class ViewControllerCustom: UIViewController {
init() {
self.hidesBottomBarWhenPushed = true
}
override func viewDidAppear(animated: Bool) {
self.hidesBottomBarWhenPushed = false
}
}
And then in every UIViewController's custom implementation of BarButtonItemBack pressed I check to see if the previous view controller (that will be popped to needs to hide the tab bar). Granted I abstracted this out into a general function so I didn't need to repeat code, but here's the concept. Thanks for the help figuring this out though!
func barButtonItemBackPressed(button: UIButton) {
var viewControllers = self.navigationController!.viewControllers as! [UIViewController]
if ((viewControllers[viewControllers.count - 2]).isKindOfClass(ViewControllerCustom.self)) {
(viewControllers[viewControllers.count - 2] as! ViewControllerCustom).hidesBottomBarWhenPushed = true
}
self.navigationController?.popViewControllerAnimated(true)
}
I believe the intended use of this property is to hide the bar when pushed. So, when your view controller appears after the top-most one is popped, it wasn't pushed on the stack, so it doesn't change the tab bar's appearance.
This leaves you with two options:
1) Keep the bottom bar for all view controllers. When text is being entered, the keyboard covers the bottom bar.
2) Hide the bottom bar for View Controller A, as well as any other view controller that is pushed on top of A.