swift hiding navbar in mmdrawercontroller - ios

I have created a slidout menu for kmy app with mmdrawercontroller from github.
It all works perfectly but i can't get rid of the nav bar at the top. it is overlapping part of my many but also shows up on all other pages. I need it gone. i have found the following code
navigationController?.setNavigationBarHidden(navigationController?.navigationBarHidden == false, animated: true)
But i have no idea where to place it. I tried it in appdelegate, in the leftsliderviewcontroller, in the button who invokes the mmdrawercontroller. But nothing seems to work.
Also in code that comes with the mmdrawercontroller i can't find anywhere a bool for this setting.
Can any one show me how to hide this navigationbar.
thanks.

If you want to hide your UINavigationBar in some UIViewControllers the you need to call self.navigationController?.navigationBarHidden = true in your viewWillAppear like in the following way:
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.navigationBarHidden = true
}
And the above code hide your UINavigationBar. I hope this help you.

Related

Two NavigationBar Showing

Hi I am new to Swift and am trying to build an app with multiple Views..
My first View(initial view) is embedded in navigation controller.
My Second View is embedded in Tab Bar Controller
My Third View is again embedded in a Navigation Controller.
The problem is that on my third view I see to navigation Controller with the top one taking me back to First View and the below one taking me to Second View.
Is it an incorrect way of doing this? I want to get rid of navigation bar that came from 1st view.
Thanks in anticipation.
PS : I had initially not attempted Navigation Bar on 3rd View.. but the problem was that I am also not able to map Bar Button Item and hence to embed the 3rd View too in a separate Navigation Controller
While it shows perfect in Xcode.. it shows 2 NavBar on the simulator
Not an elegant solution but still this can solve your problem. On your controller embed to UITabBarController where you have added Next Button. Add the below code on that controller class.
On ViewWillappear add show nav bar and on viewDidDisappear hide nav bar as shown in below code
ON viewWillAppear:
override func viewWillAppear(_ animated: Bool) {
self.navigationController.navigationBar.isHidden = false
}
ON viewDidDisappear:
override func viewDidDisappear(_ animated: Bool) {
self.navigationController.navigationBar.isHidden = true
}

Completely disable the Navigation Controller

I have used the 'Embed In' navigation controller within the storyboard. Is there a way to completely disable the whole navigation bar? I have tried the code below, but when there is a swipe, the navigation bar appears again. I want to be able to completely hide the whole bar until a condition is met. Is there a way to do this?
self.navigationController?.hidesBarsOnSwipe = true
self.navigationController?.hidesBarsOnTap = true
I have tried a custom navigation bar, but I couldn't get a nice scroll effect like with the default navigation bar.
To hide the navigationBar just do:
self.navigationController?.navigationBar.isHidden = true
Add this row in your viewDidLoad.
You can use this in viewDidLoad:
self.navigationController?.setNavigationBarHidden(true, animated: false)

Adding a navigation controller programmatically for the second VC

In my storyboard, I have setup a navigation controller points to my MainVC, and it works just fine.
And now, I'm trying to add another view called "HelpVC", and I created one in the storyboard. It automatically shows the navigation bar on the top.
(MainVC segues to HelpVC)
However, I did everything else in code.
I had initWithView in the HelpVC which draws out the interface, BUT the navigation bar does not show up, so I can't go back to that previous view controller.
How do I make sure that the navigation bar shows up and works just like other view controllers? (segue back to the last view?)
It is not very clear from the post, but as I understood, you may want to try:
override func viewWillAppear(_ animated: Bool){
super.viewWillAppear(animated)
self.navigationController?.isNavigationBarHidden = false
}

Disable swipe back gesture in Swift

Been looking around on here for a while but can't seem to find a working solution.
I'm trying to disable the swipe to go back to previous view gesture, in Swift.
I've tried a variety of solutions including:
self.navigationController?.interactivePopGestureRecognizer.enabled = false
and
self.navigationController.interactivePopGestureRecognizer.delegate = self
func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer!) -> Bool {
return false
}
Is there a new method of doing this or some other method that works?
The following is an easy approach to disabling & re-enabling the swipe back.
Swift 3.x & up
In a viewDidLoad/willAppear/didAppear method add:
navigationController?.interactivePopGestureRecognizer?.isEnabled = false
Just keep in mind that if you do it with viewDidLoad, then the next time you open the view, it may not be set depending upon whether or not it remains in your stack.
Unless you want it to remain off, you will need to turn it back on when the view is closed via either willMove(toParentViewController:) or willDisappear. Your navigationController will be nil at viewDidDisappear, so that is too late.
navigationController?.interactivePopGestureRecognizer?.isEnabled = true
A special note on SplitViewControllers:
As pointed out by CompC in the comments, you will need to call the second navigation controller to apply it to a detail view as such:
navigationController?.navigationController?.interactivePopGe‌​stureRecognizer?.isE‌​nabled = false
Swift 2.2 & Objective-C
Swift versions 2.x & below:
navigationController?.interactivePopGestureRecognizer?.enabled
Objective-C:
self.navigationController.interactivePopGestureRecognizer.enabled
You could disable it but that would not be to recommended as most iOS users go back by swiping and less by pressing the back button.
If you want to disable it it would be more reasonable to use a modal segue instead of a push segue which is not that big of a transfer.
If you really want to get rid of the swipe to go back function I would just disable the back button and have a done button on the top right of the screen.
self.navigationController?.navigationItem.backBarButtonItem?.isEnabled = false;
I was able to do this by returning false in gestureRecognizerShouldBegin
class ViewController2: UIViewController, UIGestureRecognizerDelegate {
...
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.navigationController?.interactivePopGestureRecognizer.delegate = self
}
func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
return false
}
Add this line before pushing view controller to navigation controller
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false
Nothing wrong with either answer from Hari or Stefan but this is more succinct. Just put it in viewDidLoad and you're done.
if navigationController!.respondsToSelector(Selector("interactivePopGestureRecognizer")) {
navigationController!.view.removeGestureRecognizer(navigationController!.interactivePopGestureRecognizer)
}
EDIT:
One small caveat is that if the Navigation Controller was opened by another view and the Navigation Controller is closed then you'll get an EXC_BAD_ACCESS error. To fix it you have to save the original UIGestureRecognizer and put it back when you exit the view.
Declare:
private var popGesture: UIGestureRecognizer?
Immediately before removing the gesture:
popGesture = navigationController!.interactivePopGestureRecognizer
Then when closing the view:
If popGesture != nil {
navigationController!.view.addGestureRecognizer(popGesture!)
}
RowanPD's logic for Swift 4
private var popGesture: UIGestureRecognizer?
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if navigationController!.responds(to: #selector(getter: UINavigationController.interactivePopGestureRecognizer)) {
self.popGesture = navigationController!.interactivePopGestureRecognizer
self.navigationController!.view.removeGestureRecognizer(navigationController!.interactivePopGestureRecognizer!)
}
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if let gesture = self.popGesture {
self.navigationController!.view.addGestureRecognizer(gesture)
}
}
Instead of
self.navigationController.pushViewController(VC, animated: Bool)
call
self.navigationController.setViewContollers([VC], animated: Bool)
setViewControllers replaces the all the VCs on the stack, instead of adding a new controller on top. This means that the new set VC is the root VC, and the user cannot go back.
This is most effective when you only want to disable the swipe on a single VC, and keep the swipe-to-back for the other VC.
If you want users to be able to go back, just not through swiping, do not use this method as it will disable all backs (as there is no VC to go back to).
for objective -c
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:true];
self.navigationController.interactivePopGestureRecognizer.enabled = NO;
}
This is something you missed if it doesn't work after you tried all.
Add navigationController?.interactivePopGestureRecognizer?.isEnabled = false
to your viewWillAppear(animated:) method.
if it doesn't work, remove navigation delegate from the view controller. Check again if your view controller is confirming UINavigationControllerDelegate, UIGestureRecognizerDelegate protocols. if so, just remove it.
I generally make sure that swipe back is enabled in as many places as possible, even adding a custom gesture recognizer to add it to modal screens. However for an authentication and download process in my app I start the process with a modal navigation controller and then push the view for each next step. However, once it's completed I want to prevent them from backing up into the authentication screens.
For this scenario I've been using:
navigationController?.interactivePopGestureRecognizer?.isEnabled = false
navigationItem.hidesBackButton = true
in viewWillAppear() on the final screen. You can undo these in viewWillDisappear() if you're pushing another view and need them there.
Come here a little bit late. In my case self.navigationController?.navigationItem.backBarButtonItem?.isEnabled = false; not working. So I do this: you can present view controller instead of push view controller. This way the swipe back gesture will not apply to the view controller.
navigationController?.present(vc, animated: true)
You could use dismiss for your custom back button
self.dismiss(animated: true)
Note: You could set VC modal presentation style before present it to make sure it's full screen.
vc.modalPresentationStyle = .fullScreen
Hope this help.
If requirement is to show side menu on some of the screens then add AddScreenEdgePanGesture on this specific view instead of navigationController view
replace it
SideMenuManager.default.menuAddScreenEdgePanGesturesToPresent(toView: self.navigationController?.view)
with this
SideMenuManager.default.menuAddScreenEdgePanGesturesToPresent(toView: self.view)
Only complete removal of the gesture recognizer worked for me (from the presenting view controller).
if let navigationController = parent.navigationController,
let interactivePopGestureRecognizer = navigationController.interactivePopGestureRecognizer {
navigationController.view.removeGestureRecognizer(interactivePopGestureRecognizer)
}
Don't Use this if you don't want to come back, or you set the new rootViewController.
self.navigationController.pushViewController(VC, animated: Bool)
Use this
self.navigationController.setViewContollers([VC], animated: Bool)
setViewControllers Remove all the View Controllers on the stack then the user cannot go back. it will disable all backs
this worked for me
gesture(DragGesture(minimumDistance: 10, coordinateSpace: .global))
so minimum distance is the distance to which drag gesture start listening, setting to 0 removes any listening, but it will remove all interactions be aware, i have changed 0 to 10 to listen to tap gestures, but in your screen if you have any other interaction it will not work after adding this,
If you don't care about system back button appearance (for example, if you're using custom back button or navigation bar is hidden at all), it might help you:
navigationItem.hidesBackButton = true
It hides back button and disables swipe back gesture.

UINavigationController without navigation bar?

I have a universal app, and on the iPad version I'm using UISplitViewController to create an interface similar to the Mail app.
I was having trouble pushing new Detail views, so I decided to use a UINavigationController so I could just push and pop views as needed. However, I do not want to use the navigation view or a toolbar. But no matter what I do, I can't hide the navigation bar.
I've tried unchecking "Shows Navigation Bar" in IB, and I've also tried setting:
[self.navigationController setNavigationBarHidden:YES];
in the viewDidLoad/viewDidAppear/viewWillAppear. I've also tried it in each of the views that will be pushed. Nothing works.
Is there something I'm missing here? Is it possible to have a UINavigationController without a toolbar or navigation bar?
You should be able to do the following:
self.navigationController.navigationBar.isHidden = true //Swift 5
where self.navigationController is (obviously) an instance of UINavigationController. Seems to work for me, but I only briefly tested it before posting this.
In Xcode 4.3.2:
Select the navigation controller in the storyboard
Select the Attributes Inspector in the (right) Utilities panel
Under the Navigation Controller category you have two check boxes:
[] Shows Navigation Bar
[] Shows Toolbar
Worked for me...
If you want no navigation bar, and you want the content to be adjusted up to where the navigation bar normally would be, you should use
self.navigationController.navigationBarHidden = YES;
This gives you a result like this:
Whereas self.navigationController.navigationBar.hidden = YES; gives you a space where the navigationBar should be. Like this:
Swift 4
I hide it in viewWillAppear
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.isNavigationBarHidden = true;
}
Then you can put it back when you push a segue (if you want to have the back button on the next view)
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
self.navigationController?.isNavigationBarHidden = false;
}
Swift 3 Programmatically
self.navigationController.isNavigationBarHidden = true
or
self.navigationController.navigationBar.isHidden = true
Note: I didn't see a difference between these two approaches testing on iOS 10.
All these answers still leave a space at the top for the status bar - add this line to remove that as well:
navController.navigationBar.isHidden = true
navController.accessibilityFrame = CGRect.zero

Resources