2009-08-14 6 views
2

Ich manuell eine UINavigationBar für meine Ansicht verwalten. Die Leiste selbst und das erste UINavigationItem werden im Interface Builder erstellt. In meinem Code, basierend auf verschiedenen Ereignissen, drücke ich neue Navigationselemente auf die Leiste und male die entsprechenden Ansichten als Unteransichten der Hauptansicht. Alles scheint in Ordnung zu sein, aber wenn ich den Navbar-Zurück-Button wähle, werden zwei Items vom Item-Stack entfernt, anstatt 1, wie ich es erwartet hätte. Um zu testen, habe ich meinen Controller als Delegierten für die Bar und Trap 2 Delegatmethoden:UINavigationBar scheint 2 Objekte aus dem Stapel auf "zurück" zu knallen

- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item; 

und

- (void)navigationBar:(UINavigationBar *)navigationBar didPopItem:(UINavigationItem *)item; 

ich direkt vor dem Pop gefunden, die Elemente in der Navigationsleiste sind richtig, Zum Beispiel, 3. In der zweiten Methode, gleich nach dem Pop, ist die Elemente 1, obwohl das Element Pop ist das letzte Element - irgendwie fehlt das mittlere Element. Ich bin ratlos, wie das zu debuggen und würde mich über jede Idee freuen.

Beachten Sie, dass ich aus verschiedenen Gründen keinen Navigationscontroller verwende.

Antwort

0

"Ich verwalte manuell eine UINavigationBar für meine Ansicht."

Tun Sie das nicht. ;-)

Ernsthaft. Ich kann mir keinen guten Grund vorstellen, es selbst zu verwalten, und wenn Sie nicht sehr vorsichtig sind, werden Sie auf Probleme stoßen, die die ganze App unüberschaubar machen. Warum also nicht einfach einen UINavigationController in Ihrer Root-Ansicht erstellen, der mit Ihrem XIB verbunden ist? Welches Problem versuchen Sie zu überwinden, indem Sie die Navigationsleiste selbst verwalten?

In Bezug auf das Problem, das Sie haben - Sie erhalten zwei Pops, weil Sie etwas in sortPopItem tun, die es wieder Pop sagt. Das ist ein Effekt, wenn Sie versuchen, die Navigationsleiste selbst zu verwalten. Beachten Sie, dass sich die Parameter sophopItem und didPopItem nur auf die Navigationsleiste und nicht auf den Navigationscontroller und die Ansichten beziehen. Wenn Sie einen Ansichtscontroller mit [[self navigationController] popViewControllerAnimated: YES]; Es ruft sallPopItem auf. Da Sie das übersteuern, müssen Sie alles verwalten.

+0

Ja, danke. Ich dachte, dass vielleicht etwas didPopItem und shallPopItem zweimal aufgerufen hat, weshalb ich die Delegate-Methoden eingerichtet habe, damit ich diese abfangen konnte. Sie werden nur einmal angerufen. Damals schien es einfacher, meinen Viewcontroller zu erweitern, als den Navigationscontroller zu implementieren. Und da IB Ihnen die Werkzeuge zur Verfügung stellt, um das einzurichten, dachte ich, es wäre OK. Außerdem bin ich ziemlich neu in iphone dev und mag die Framework-Mechanik zu verstehen. Ich habe mich jetzt darum gekümmert und habe dies noch einmal mit der Umgebung in Verbindung gebracht, die meinem Verständnis entgangen ist ... – farhadf

0

würde ich, indem eine NSLog() Aussage zu Beginn Ihrer shouldPopItem und didPopItem Methoden starten - Ihnen eine Vorstellung davon geben, wie oft sie immer genannt, und wann. Als Nächstes können Sie die Größe des View-Controller-Stacks an verschiedenen Stellen in Ihrer App protokollieren, sodass Sie sehen können, wie sie vergrößert und verkleinert wird. Wenn keiner von beiden funktioniert, beginnen Sie einfach mit dem Setzen von Haltepunkten und überprüfen Sie Stack-Traces/View-Controller-Stack-Größe manuell.

+0

Danke - Ich war nicht sehr sauber in meiner Post - das ist genau das, was ich tat - Setzen von Haltepunkten und Anzeigen der Größe des Stapels und was auf dem Stapel ist. Sehr eigenartig. – farhadf

0

Es ist fast nie akzeptabel, Kernklassen wie UINavigationController zu ersetzen oder auszuschließen. Vertrau mir, ich habe jemanden gesehen, der das ausgiebig gemacht hat, und die App war voller Probleme - und ich musste mit ihnen umgehen. Werfen Sie einen Blick auf UINavigationController.h. Es verwaltet eine Tonne Staat usw. Warum versuchen Sie, Ihre eigene Navigationsleiste zu verwalten?

Stattdessen ist es akzeptabel, "leicht" Unterklassen wie UINavigationBar zu überschreiben nur bestimmte Zeichnung/Layout-Methoden. Dadurch kann die komplizierte Logik wie beabsichtigt auf die Basisklassen zurückfallen.

noch besser, machen nur die Verwendung des contents Eigenschaft der Navigationsleiste, wenn alles, was Sie suchen, ist zu tun Stil es mit, sagen wir, ein benutzerdefiniertes Bild:

#import <QuartzCore/QuartzCore.h> 
... 
- (void)viewDidLoad 
{ 
    UIImage * navigationBarContents = [UIImage imageNamed:@"navigation-bar"]; 
    self.navigationController.navigationBar.layer.contents = 
     (id)navigationBarContents.CGImage; 
} 

Sie können dies für jede tun UIView Unterklasse, um einfach und sauber die Art und Weise ändern, wie sie mit Bildern aussehen. Natürlich, wenn Sie benutzerdefinierte Zeichnung tun, nur Unterklasse UINavigationBar und überschreiben nur die -drawRect: Methode. Verwenden Sie dann diese Unterklasse anstelle von UINavigationBar mit einem Standard UINavigationController, und alles funktioniert genauso wie es normalerweise nur mit Ihrer benutzerdefinierten Navigationsleiste funktionieren würde.

0

Ich weiß nicht, warum UINavigationBar verhält sich so, aber ich habe eine knifflige Lösung.

- (BOOL)navigationBar:(UINavigationBar *)navigationBar 
    shouldPopItem:(UINavigationItem *)item 
{ 
    NSMutableArray *items = navigationBar.items.mutableCopy; 
    [items removeObject:item]; 

    // Now var 'items' contains the proper instances of UINavigationItem. To be exact, one more than the instances in 'navigationBar.items'. 

    return YES; 
} 
0

prüfen, ob die poppage wird Benutzer initiiert oder programmatische wie so

- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item 
{ 
    UIViewController *topViewController = self.topViewController; 

    ... some logic that justifies implementing shouldPopItem: delegate in the first place -> others have explained the caveats so I won't repeat that ... 

    // manual as in opposite of programmatic 
    BOOL manualPop = topViewController.navigationItem == item; 
    if(manualPop) { 
     [self popViewControllerAnimated:YES]; 
    } 
    return YES; 
} 
Verwandte Themen