wake-up-neo.com

iPhone Navigationsleiste nur auf der ersten Seite ausblenden

Ich habe den Code darunter, der die Navigationsleiste verbirgt und zeigt. Sie wird beim Laden der ersten Ansicht ausgeblendet und beim Aufrufen der "Kinder" ausgeblendet. Das Problem ist, dass ich das Ereignis/die Aktion nicht finden kann, um sie wieder auszublenden, wenn sie zur Stammansicht zurückkehren.

Ich habe eine "Test" -Schaltfläche auf der Stammseite, die die Aktion manuell ausführt, aber nicht hübsch ist, und ich möchte, dass sie automatisch ausgeführt wird.

-(void)hideBar 
{
    self.navController.navigationBarHidden = YES;
}
-(void)showBar 
{       
    self.navController.navigationBarHidden = NO;
}
368
Lee Armstrong

Die schönste Lösung, die ich gefunden habe, ist das Folgende im first view controller.

Ziel-C

- (void)viewWillAppear:(BOOL)animated {
    [self.navigationController setNavigationBarHidden:YES animated:animated];
    [super viewWillAppear:animated];
}

- (void)viewWillDisappear:(BOOL)animated {
    [self.navigationController setNavigationBarHidden:NO animated:animated];
    [super viewWillDisappear:animated];
}

Swift

override func viewWillAppear(animated: Bool) {
    self.navigationController?.setNavigationBarHidden(true, animated: animated)
    super.viewWillAppear(animated)
}

override func viewWillDisappear(animated: Bool) {
    self.navigationController?.setNavigationBarHidden(false, animated: animated)
    super.viewWillDisappear(animated)
} 

Dadurch wird die Navigationsleiste von links (zusammen mit der nächsten Ansicht) animiert, wenn Sie das nächste UIViewController auf dem Stapel verschieben, und nach links (zusammen mit der alten Ansicht) animiert, wenn Sie Drücken Sie die Zurück-Taste auf dem UINavigationBar.

Beachten Sie auch, dass dies keine delegierten Methoden sind, Sie die Implementierung dieser Methoden durch UIViewController überschreiben und gemäß der Dokumentation Sie müssen die Implementierung des Super irgendwo in Ihrer Implementierung aufrufen.

1009
Alan Rogers

Ein anderer Ansatz, den ich gefunden habe, besteht darin, einen Delegaten für das NavigationController festzulegen:

navigationController.delegate = self;

und benutze setNavigationBarHidden in navigationController:willShowViewController:animated:

- (void)navigationController:(UINavigationController *)navigationController 
      willShowViewController:(UIViewController *)viewController 
                    animated:(BOOL)animated 
{   
    // Hide the nav bar if going home.
    BOOL hide = viewController != homeViewController;
    [navigationController setNavigationBarHidden:hide animated:animated];
}

Einfache Möglichkeit, das Verhalten für jedes ViewController an einem Ort anzupassen.

47
Chad M.

Eine kleine Änderung, die ich bei den anderen Antworten vornehmen musste, besteht darin, die Leiste in viewWillDisappear nur dann einzublenden, wenn der Grund dafür, dass sie verschwindet, darin liegt, dass ein Navigationselement darauf verschoben wurde. Dies liegt daran, dass die Ansicht aus anderen Gründen ausgeblendet werden kann.

Daher schalte ich die Leiste nur ein, wenn diese Ansicht nicht mehr die oberste Ansicht ist:

- (void) viewWillDisappear:(BOOL)animated
{
    if (self.navigationController.topViewController != self)
    {
        [self.navigationController setNavigationBarHidden:NO animated:animated];
    }

    [super viewWillDisappear:animated];
}
17
user486646

Ich würde den Code in den viewWillAppear -Delegaten für jede angezeigte Ansicht einfügen:

So, wo du es verstecken musst:

- (void)viewWillAppear:(BOOL)animated
{
        [yourObject hideBar];
}

So, wo du es zeigen musst:

- (void)viewWillAppear:(BOOL)animated
{
        [yourObject showBar];
}
16

in Swift 3:

override func viewWillAppear(_ animated: Bool) {
    navigationController?.navigationBar.isHidden = true
    super.viewWillAppear(animated)
}


override func viewWillDisappear(_ animated: Bool) {
    if (navigationController?.topViewController != self) {
        navigationController?.navigationBar.isHidden = false
    }
    super.viewWillDisappear(animated)
}
14

Die aktuell akzeptierte Antwort stimmt nicht mit dem in der Frage beschriebenen beabsichtigten Verhalten überein. Die Frage fordert dazu auf, dass die Navigationsleiste auf dem Stammansichts-Controller ausgeblendet, aber überall sichtbar ist. Die akzeptierte Antwort verbirgt jedoch die Navigationsleiste auf einem bestimmten Ansichts-Controller. Was passiert, wenn eine andere Instanz des First View Controllers auf den Stack geschoben wird? Die Navigationsleiste wird ausgeblendet, obwohl der Root-View-Controller nicht angezeigt wird.

Stattdessen ist @Chad Ms Strategie der Verwendung von UINavigationControllerDelegate eine gute und hier eine vollständigere Lösung. Schritte:

  1. Unterklasse UINavigationController
  2. Implementiere das -navigationController:willShowViewController:animated-Methode zum Anzeigen oder Ausblenden der Navigationsleiste, je nachdem, ob der Stammansichts-Controller angezeigt wird
  3. Überschreiben Sie die Initialisierungsmethoden, um die UINavigationController-Unterklasse als eigenen Delegaten festzulegen

Den vollständigen Code für diese Lösung finden Sie in this Gist . Hier ist die navigationController:willShowViewController:animated Implementierung:

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    /* Hide navigation bar if root controller */
    if ([viewController isEqual:[self.viewControllers firstObject]]) {
        [self setNavigationBarHidden:YES animated:animated];
    } else {
        [self setNavigationBarHidden:NO animated:animated];
    }
}
12
hunteros

Nach mehreren Versuchen hier ist, wie ich es für das arbeiten bekam, was ich wollte. Das habe ich versucht. - Ich habe eine Ansicht mit einem Bild. und ich wollte, dass das Bild im Vollbildmodus angezeigt wird. - Ich habe auch einen Navigationscontroller mit einer TabBar. Also muss ich das auch verstecken. - Außerdem bestand meine Hauptanforderung darin, mich nicht nur zu verstecken, sondern beim Ein- und Ausblenden auch einen verblassenden Effekt zu erzielen.

So habe ich es funktioniert.

Schritt 1 - Ich habe ein Bild und der Benutzer tippt einmal auf dieses Bild. Ich nehme diese Geste auf und drücke sie in das neue imageViewController, das sich im imageViewController befindet. Ich möchte ein Vollbild haben.

- (void)handleSingleTap:(UIGestureRecognizer *)gestureRecognizer {  
NSLog(@"Single tap");
ImageViewController *imageViewController =
[[ImageViewController alloc] initWithNibName:@"ImageViewController" bundle:nil];

godImageViewController.imgName  = // pass the image.
godImageViewController.hidesBottomBarWhenPushed=YES;// This is important to note. 

[self.navigationController pushViewController:godImageViewController animated:YES];
// If I remove the line below, then I get this error. [CALayer retain]: message sent to deallocated instance . 
// [godImageViewController release];
} 

Schritt 2 - Alle folgenden Schritte befinden sich im ImageViewController

Schritt 2.1 - Zeigen Sie in ViewDidLoad die Navigationsleiste an

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
NSLog(@"viewDidLoad");
[[self navigationController] setNavigationBarHidden:NO animated:YES];
}

Schritt 2.2 - Richten Sie in viewDidAppear einen Timer-Task mit Verzögerung ein (ich habe ihn auf eine Verzögerung von 1 Sekunde eingestellt). Fügen Sie nach der Verzögerung einen Fading-Effekt hinzu. Ich benutze Alpha, um Fading zu verwenden.

- (void)viewDidAppear:(BOOL)animated
{
NSLog(@"viewDidAppear");

myTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self     selector:@selector(fadeScreen) userInfo:nil repeats:NO];
}

- (void)fadeScreen
{
[UIView beginAnimations:nil context:nil]; // begins animation block
[UIView setAnimationDuration:1.95];        // sets animation duration
self.navigationController.navigationBar.alpha = 0.0;       // Fades the alpha channel of   this view to "0.0" over the animationDuration of "0.75" seconds
[UIView commitAnimations];   // commits the animation block.  This Block is done.
}

schritt 2.3 - Fügen Sie unter viewWillAppear dem Bild eine einzelne Tippen-Geste hinzu und machen Sie die Navigationsleiste durchscheinend.

- (void) viewWillAppear:(BOOL)animated
{

NSLog(@"viewWillAppear");


NSString *path = [[NSBundle mainBundle] pathForResource:self.imgName ofType:@"png"];

UIImage *theImage = [UIImage imageWithContentsOfFile:path];

self.imgView.image = theImage;

// add tap gestures 
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];  
[self.imgView addGestureRecognizer:singleTap];  
[singleTap release];  

// to make the image go full screen
self.navigationController.navigationBar.translucent=YES;
}

- (void)handleTap:(UIGestureRecognizer *)gestureRecognizer 
{ 
 NSLog(@"Handle Single tap");
 [self finishedFading];
  // fade again. You can choose to skip this can add a bool, if you want to fade again when user taps again. 
 myTimer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self  selector:@selector(fadeScreen) userInfo:nil repeats:NO];
 }

Schritt 3 - Stellen Sie schließlich in viewWillDisappear sicher, dass Sie alle Daten zurücksetzen

- (void)viewWillDisappear: (BOOL)animated 
{ 
self.hidesBottomBarWhenPushed = NO; 
self.navigationController.navigationBar.translucent=NO;

if (self.navigationController.topViewController != self)
{
    [self.navigationController setNavigationBarHidden:NO animated:animated];
}

[super viewWillDisappear:animated];
}
6
verma

Gib meine Anerkennung für die Antwort von @ chad-m.

Hier ist die Swift Version:

  1. Erstelle eine neue Datei MyNavigationController.Swift

import UIKit

class MyNavigationController: UINavigationController, UINavigationControllerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        self.delegate = self
    }

    func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
        if viewController == self.viewControllers.first {
            self.setNavigationBarHidden(true, animated: animated)
        } else {
            self.setNavigationBarHidden(false, animated: animated)
        }
    }

}
  1. Setzen Sie die Klasse Ihres UINavigationControllers in StoryBoard auf MyNavigationController MyNavigationController Das war's!

Unterschied zwischen der Antwort von chad-m und meiner:

  1. Erben Sie von UINavigationController, damit Sie Ihren rootViewController nicht verunreinigen.

  2. verwenden self.viewControllers.first statt homeViewController, sodass Sie dies nicht 100 Mal für Ihre 100 UINavigationController in 1 StoryBoard ausführen.

4
AI Lion

Für den Fall, dass jemand immer noch Probleme mit dem Fehler Fast Backswipe Cancelled hat, wie @fabb in der akzeptierten Antwort kommentiert.

Ich schaffe es, dies zu beheben, indem ich viewDidLayoutSubviews überschreibe, zusätzlich zu viewWillAppear/viewWillDisappear Wie nachfolgend dargestellt:

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    self.navigationController?.setNavigationBarHidden(false, animated: animated)
}

override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)
    self.navigationController?.setNavigationBarHidden(true, animated: animated)
}

//*** This is required to fix navigation bar forever disappear on fast backswipe bug.
override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    self.navigationController?.setNavigationBarHidden(false, animated: false)
}

In meinem Fall stelle ich fest, dass dies daran liegt, dass der Root-View-Controller (bei dem nav ausgeblendet ist) und der Push-View-Controller (bei dem nav angezeigt wird) unterschiedliche Statusleistenstile haben (z. B. dunkel und hell) . Sobald Sie den Backswipe starten, um den View Controller zu öffnen, wird eine zusätzliche Farbanimation in der Statusleiste angezeigt. Wenn Sie den Finger loslassen, um den interaktiven Pop abzubrechen, solange die Statusleistenanimation noch nicht abgeschlossen ist, ist die Navigationsleiste für immer verschwunden!

Dieser Fehler tritt jedoch nicht auf, wenn die Statusleistenstile beider Ansichtscontroller identisch sind.

3
aunnnn

Wenn Sie die Navigationsleiste vollständig im Controller ausblenden möchten, ist es eine viel sauberere Lösung, im Root-Controller Folgendes zu haben:

@implementation MainViewController
- (void)viewDidLoad {
    self.navigationController.navigationBarHidden=YES;
    //...extra code on view load  
}

Wenn Sie eine untergeordnete Ansicht in der Steuerung verschieben, bleibt die Navigationsleiste ausgeblendet. Wenn Sie es nur im untergeordneten Element anzeigen möchten, fügen Sie den Code zum Anzeigen von it(self.navigationController.navigationBarHidden=NO;) im viewWillAppear-Rückruf hinzu. Ebenso den Code zum Ausblenden in viewWillDisappear.

1
Alex

Die einfachste Implementierung kann darin bestehen, dass jeder Ansichtscontroller angibt, ob seine Navigationsleiste in seiner viewWillAppear:animated: - Methode ausgeblendet ist oder nicht. Der gleiche Ansatz eignet sich auch zum Ausblenden/Anzeigen der Symbolleiste:

- (void)viewWillAppear:(BOOL)animated {
    [self.navigationController setToolbarHidden:YES/NO animated:animated];
    [super viewWillAppear:animated];
}
0
SteveCaine

Das Ausblenden der Navigationsleiste nur auf der ersten Seite kann auch über das Storyboard erfolgen. Im Storyboard gehe zu Navigation Controller Scene-> Navigation Bar. Wählen Sie im Attributes-Inspector die Eigenschaft 'Hidden' aus. Dadurch wird die Navigationsleiste ab dem ersten Viewcontroller ausgeblendet, bis sie für den erforderlichen Viewcontroller sichtbar wird.

Die Navigationsleiste kann im ViewWillAppear-Rückruf von ViewController wieder sichtbar gemacht werden.

-(void)viewWillAppear:(BOOL)animated {

    [self.navigationController setNavigationBarHidden:YES animated:animated];
    [super viewWillAppear:animated];                                                  
}
0
RSG

Swift 4:

Im View-Controller möchten Sie die Navigationsleiste ausblenden.

override func viewWillAppear(_ animated: Bool) {
    self.navigationController?.setNavigationBarHidden(true, animated: animated)
    super.viewWillAppear(animated)
}

override func viewWillDisappear(_ animated: Bool) {
    self.navigationController?.setNavigationBarHidden(false, animated: animated)
    super.viewWillDisappear(animated)
}
0
John Riselvato