ChatGPT解决这个技术问题 Extra ChatGPT

I have an app with a navigation bar consisting of 2 bar buttons. I would like to hide and show this navigation bar when a user double taps the screen.

Initially, the navigation bar should be hidden. When a user double taps the screen, the navigation bar should come up with an animation, like what can be seen in the iPhone's photo gallery.

How can i do something this? Suggestions are always appreciated.


C
Carmen

This isn't something that can fit into a few lines of code, but this is one approach that might work for you.

To hide the navigation bar:

[[self navigationController] setNavigationBarHidden:YES animated:YES];

To show it:

[[self navigationController] setNavigationBarHidden:NO animated:YES];

Documentation for this method is available here.

To listen for a "double click" or double-tap, subclass UIView and make an instance of that subclass your view controller's view property.

In the view subclass, override its -touchesEnded:withEvent: method and count how many touches you get in a duration of time, by measuring the time between two consecutive taps, perhaps with CACurrentMediaTime(). Or test the result from [touch tapCount].

If you get two taps, your subclassed view issues an NSNotification that your view controller has registered to listen for.

When your view controller hears the notification, it fires a selector that either hides or shows the navigation bar using the aforementioned code, depending on the navigation bar's current visible state, accessed through reading the navigation bar's isHidden property.

EDIT

The part of my answer for handling tap events is probably useful back before iOS 3.1. The UIGestureRecognizer class is probably a better approach for handling double-taps, these days.

EDIT 2

The Swift way to hide the navigation bar is:

navigationController?.setNavigationBarHidden(true, animated: true)

To show it:

navigationController?.setNavigationBarHidden(false, animated: true)

If this is for a photo viewer application, hiding the nav bar causes an unpleasant jump for the image view, which I haven't found how to prevent. 3.2 lets you use UIGestureRecognizer for double taps, which is a much neater approach (for iPad only atm).
Thanks a lot Alex,u provided me a lot of infoemation,i m gonna follow ur guidelines .. thanks a ton
is this same applied for tab bars??? if i want to hide/show tab bars dan wat i hv to do? regards shishir
Is there any way to prevent this 'jump' Paul mentioned? I have the very same problem and I do not know, what causes it.... neither do I think, noone ever stumbled upon it.
To stop the 'jump' from occurring you have to reset the contentInset property of the scrollview as jclee mentions, after hiding/showing the navigation bar. ie. self.scrollView.contentInset = UIEdgeInsetsZero
P
Perjan Duro

This code will help you.

UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] 
initWithTarget:self action:@selector(showHideNavbar:)];
[self.view addGestureRecognizer:tapGesture];

-(void) showHideNavbar:(id) sender 
{ 
// write code to show/hide nav bar here 
// check if the Navigation Bar is shown
if (self.navigationController.navigationBar.hidden == NO)
{
// hide the Navigation Bar
[self.navigationController setNavigationBarHidden:YES animated:YES];
}
// if Navigation Bar is already hidden
else if (self.navigationController.navigationBar.hidden == YES)
{
// Show the Navigation Bar
[self.navigationController setNavigationBarHidden:NO animated:YES];
}
}

j
jclee

First read the the section in the View Controller Programming Guide for iOS about 'Adopting a Full-Screen Layout for Navigation Views' and the section about the same for Custom Views. If you are trying to do something like the Photos.app then you are probably using a scroll view. Note the comment that Navigation bars automatically add a scroll content inset to your scroll view to account for the height of the navigation bar (and status bar) so you have to reset the contentInset property of your scroll view back to zero (UIEdgeInsetsZero) right after setting up the initial state of the navigationBar and before the view appears.

Then if you have a single tap that toggles the navigationBar and/or status bar to show or hide, you need to do two things in you toggling method. The first seems to be to save the scroll view's contentOffset property before changing the NavigationBar hidden property and restore your saved value to contentOffset right afterward. And second to again zero out the contentInset property to UIEdgeInsetsZero after changing the navigationBarHidden property. Also, if you are toggling the status bar, you need to change its state before you change the navigationBar's state.


Thank you so much for the contentOffset and contentInset note. You the real hero.
I concur, you are the real hero, here! Thanks a lot.
C
Carmen

In Swift try this,

navigationController?.isNavigationBarHidden = true  //Hide
navigationController?.isNavigationBarHidden = false //Show

or

navigationController?.setNavigationBarHidden(true, animated: true) //Hide
navigationController?.setNavigationBarHidden(false, animated: true) //Show

J
Jayprakash Dubey

To hide Navigation bar :

[self.navigationController setNavigationBarHidden:YES animated:YES];

To show Navigation bar :

[self.navigationController setNavigationBarHidden:NO animated:YES];

In iOS 7, auto complete actually promotes this solution as opposed to the highest voted one.
a
amayer171292591

Here is a very quick and simple solution:

self.navigationController.hidesBarsOnTap = YES;

This will work on single tap instead of double tap. Also it will change the behavior for the navigation controller even after pushing or popping the current view controller.

You can always modify this behavior in your controller within the viewWillAppear: and viewWillDisappear: actions if you would like to set the behavior only for a single view controller.

Here is the documentation:


A
Avijit Nagare

One way could be by unchecking Bar Visibility "Shows Navigation Bar" In Attribute Inspector.Hope this help someone.

https://i.stack.imgur.com/MV4Zu.png


N
Naresh

In Swift 4.2 and Xcode 10

self.navigationController?.isNavigationBarHidden = true  //Hide
self.navigationController?.isNavigationBarHidden = false  //Show

If you don't want to display Navigation bar only in 1st VC, but you want display in 2nd VC onword's

In your 1st VC write this code.

override func viewWillAppear(_ animated: Bool) {
    self.navigationController?.isNavigationBarHidden = true  //Hide
}

override func viewWillDisappear(_ animated: Bool) {
    self.navigationController?.isNavigationBarHidden = false  //Show
}

M
Mohammad Kamran Usmani

If you want to detect the status of navigation bar wether it is hidden/shown. You can simply use following code to detect -

if self.navigationController?.isNavigationBarHidden{
    print("Show navigation bar")
} else {
    print("hide navigation bar")
}

K
Kwame 'oga' Yeboah

SWIFT CODE: This works fully for iOS 3.2 and later.

  override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)

    let tapGesture = UITapGestureRecognizer(target: self, action: "hideNavBarOntap")let tapGesture = UITapGestureRecognizer(target: self, action: "hideNavBarOntap")
    tapGesture.delegate = self
    self.view.addGestureRecognizer(tapGesture)

then write

func hideNavBarOntap() {
    if(self.navigationController?.navigationBar.hidden == false) {
        self.navigationController?.setNavigationBarHidden(true, animated: true) // hide nav bar is not hidden
    } else if(self.navigationController?.navigationBar.hidden == true) {
        self.navigationController?.setNavigationBarHidden(false, animated: true) // show nav bar
    }
}

I believe this is a poor solution, adding a tap gesture can if not configured correctly remove gestures on other views like a UITableView or UICollectionView. Also checking wether a boolean == true is redundant and can lead other programmers into thinking this is good practice. You are also misusing camel case and missing a end brace in your example. Keep in mind since swift 2.2 selectors have been updated as well. Lastly swift is only supported on iOS 7 and above and will definitely not run on iOS 3.2