7

Als Übersicht habe ich Probleme mit einem UINavigationController innerhalb eines UITabBarController aufrufen viewWillAppear aufrufen, wenn eine Ansicht aus dem Stapel entnommen wird.Probleme mit UINavigationController innerhalb von UITabBarController, viewWillAppear nicht

// Create views for Tab Bar 
    UINavigationController *view1 = [[UINavigationController alloc] initWithRootViewController:[[newsFeedNavigationController alloc] initWithStyle:UITableViewStylePlain]]; 
    resizedTabBatItem *tabBarItem1 = [[resizedTabBatItem alloc] initWithTitle:nil image:[UIImage imageNamed:@"newspaper.png"] tag:0]; 
    [view1 setTabBarItem:tabBarItem1]; 
    [tabBarItem1 release]; 

    UIViewController *view2 = [UIViewController new]; 
    resizedTabBatItem *tabBarItem2 = [[resizedTabBatItem alloc] initWithTitle:nil image:[UIImage imageNamed:@"speechbubble.png"] tag:1]; 
    [view2 setTabBarItem:tabBarItem2]; 
    [tabBarItem2 release]; 

.... 

// Create the tab bar controller 
    bookTabBarController = [BookTabBarController new]; 
    [[bookTabBarController view] setFrame:CGRectMake(0, 0, 320, 460)]; 

    // Add the views to it 
    NSArray *viewControllers = [NSArray arrayWithObjects:view1, view2, view3, view4, view5, nil]; 

    [[bookTabBarController tabBarController] setViewControllers:viewControllers]; 

Mein newsFeedNavigationController ist nur ein subclassed UITableViewController (mit viewWillAppear und die Unterklasse nicht zu stören, da sie nie in newsFeedNavigationController genannt):

Von den Delegierten wird ein UITabBarController programmatisch gemacht. Elemente, die beim Anklicken einen neuen UIViewController in den Stapel schieben.

Das Problem ist, dass viewWillAppear nie in NewsFeedNavigationController aufgerufen wird, wenn Ansichten aus dem Stapel ausgeklappt werden, und die Elemente in der Liste hervorgehoben bleiben. Ich habe mich ein paar Stunden damit beschäftigt, an dem Punkt, an dem ich Hilfe brauche, um herauszufinden, was ich falsch mache.

In meinem newsFeedNavigationController habe ich versucht, einen NSLog hinzuzufügen, um zu sehen, ob es aufgerufen wird oder ich etwas getan habe, aber es wird nie aufgerufen.

- (void)viewWillAppear:(BOOL)animated { 
    NSLog(@"is viewWillAppear called?"); 
    [super viewWillAppear:animated]; 
} 

Edit:

Okay, jetzt ist hier etwas seltsam Ich bemerkte:

Wenn ich laufen:

[self presentModalViewController:(any UIview) animated:YES]; 

und dann entlassen, beginnt viewWillAppear richtig funktioniert wenn ich poppe und Ansichten schiebe ... So, jetzt bin ich ratlos. Es ist nicht wirklich eine Lösung, sondern vielleicht ein Teil von etwas, das vor sich geht.

Antwort

1

Um meine eigene Frage zu beantworten, habe ich herausgefunden, was das Problem war.

Um Apples "No UITabBarController in einem UINavigationController" einzuhalten, habe ich meinen eigenen Tab-Bar-Controller (buildTabBarController) geschrieben, der auf einem Standard-View-Controller basiert. Mein Problem war, dass die Klasse viewDidAppear nicht an die Klasse weitergab, die die View-Controller verwaltete, also wusste sie nie, dass sie angezeigt wurde oder nicht.

+0

Ich bin verwirrt. In Ihrem Post sagten Sie "UINavigationController in einem UITabBarController" und in Ihrem Follow-up sagten Sie "UITabBarController in einem UINavigationController" ... welche? Weil ich ein identisches Problem mit einem Nav-Controller als Tab in einem Tab-Bar-Controller habe ... was, wie ich verstehe, unterstützt werden sollte. Aber ViewDidAppear beginnt erst zu arbeiten, nachdem ich eine modale Ansicht von einer der Ansichten gezeigt habe, die an den Nav-Controller weitergegeben wurden. Sehr eigenartig. – Steve

+0

Siehe meine Antwort für eine allgemeine Lösung für dieses Problem. – titaniumdecoy

+0

Das war das gleiche wie mein Problem. Es tut mir leid für die Verwirrung. Was ich ursprünglich hatte, war ein UINavigationController mit einem View-Controller, und dann würde der "Home" -Bildschirm im Wesentlichen einen UITabBarController enthalten, der als nächstes im Stapel war. Dann könnten Sie eine neue Ansicht in den Stapel schieben. Bsp .: UINavigationController w/login-Ansicht als root, wenn in, eine uitabbar eingefügt wurde und Ansichten aus einer Tabelle in das "main" -Nav geschoben werden konnten. Mein Problem war, dass viewWillAppear nicht über den Stack weitergegeben wurde (es würde von UINavigationController auf UITabBarController gehen, aber nicht auf die Ansicht der Tab-Leiste). – Dandy

1

Eine andere Lösung besteht darin, den Delegierten des Navigationssteuergeräts festzulegen. Innerhalb der Delegierten, implementieren Sie die folgende Methode:

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated { 
    [viewController viewWillAppear:animated]; 
} 

Dies wird sicherstellen, dass viewWillAppear wird auf jedem View-Controller, deren Ansicht aufgerufen ist etwa in der Navigation-Controller angezeigt werden. Wenn Sie dies auf diese Weise tun, wird viewWillAppear unabhängig davon aufgerufen, ob die Ansicht angezeigt wird, weil sie verschoben wird, oder weil sie angezeigt wird, weil eine Unteransicht aufgerufen wird.

+0

Leider habe ich diese Methode ausprobiert und es hat nicht funktioniert. Nun, es hat funktioniert, aber es hat nicht funktioniert. Das Problem war, dass obwohl viewWillAppear: animated aufgerufen wurde, es nicht an die Unteransicht in der Tab-Leiste übergeben wurde, weil es nicht explizit in der tab-Ansicht viewWillAppear aufgerufen wurde. Aber für andere auf Probleme stoßen, ist dies eine mögliche Lösung. Wenn viewWillAppear: animated nicht funktioniert, bedeutet dies wahrscheinlich, dass etwas anderes falsch ist (wie in meinem Fall). – Dandy

1

Eine Lösung für dieses Problem besteht darin, dass der UIViewController, der den UINavigationController enthält, die gewünschten Nachrichten an ihn weitergibt. Der UINavigationController leitet die Nachrichten an den entsprechenden View-Controller weiter. Es scheint widersprüchlich, aber es funktioniert.

@interface NavigationWrapperViewController : UIViewController { 
    // navigationController must be a subview of this view controller's view 
    UINavigationController *navigationController; 
} 
@property (nonatomic, assign) UINavigationController *navigationController; 
@end 

@implementation NavigationWrapperViewController 
@synthesize navigationController; 

-(void)viewWillAppear:(BOOL)animated { 
    [navigationController viewWillAppear:animated]; 
} 
-(void)viewDidAppear:(BOOL)animated { 
    [navigationController viewDidAppear:animated]; 
} 
-(void)viewWillDisappear:(BOOL)animated { 
    [navigationController viewWillDisappear:animated]; 
} 
-(void)viewDidDisappear:(BOOL)animated { 
    [navigationController viewDidDisappear:animated]; 
} 

@end

Sie können eine komplette Lösung auf Pastebin finden (was ich poste nicht).

Dank davidbenini.it und jaekwon für diese Lösung.

+0

Diese Lösung ist ein bisschen unvollständig und die Paste-bin-Verbindung ist ein bisschen eine syntaktische Unordnung, aber ich werde verdammt sein, wenn das mein Problem nicht löst! Du schaukelst! –

1

Noch einfacher Trick:

In der Unterklasse von UITabBarController, außer Kraft setzt diese:

-(void)loadView{ 

    [super loadView]; 

    //here goes the trick: 
    [self setSelectedIndex:1]; 
    [self setSelectedIndex:0]; 
} 
+0

Diese Umgehung hat mir geholfen, aber ich fand, dass es nicht funktionierte, den Index wieder auf 0 zu setzen. Ich musste warten bis ViewDidAppear. Die andere Seite wird nicht angezeigt oder flackert und behandelt einen Leckerbissen, weil die manuelle Auswahl eines anderen Tabs bedeutete, dass die problematische Ansicht funktionieren würde. Ein Nachteil ist, dass der Index, auf den Sie ihn gesetzt haben, eine sehr einfache Seite enthalten muss. Ich probierte ursprünglich eine Ansicht mit einer Unteransicht aus und die Unteransicht verschwand, konnte aber immer noch die Benutzerinteraktion aufnehmen, d. H. Das Problem wurde stattdessen auf diese Registerkarte verschoben. – RowanPD

0

OK, das ist alt, sehr alt, aber ich landete hier mit einem ähnlichen Problem auf.

UITabViewController 
    UINavigationController 
     UITableViewController1 
     UITableViewController2 

Wenn aus dem UITableViewController2, die viewWillAppear Funktion in UITableViewController1 nie genannt wurde knallen. Das Problem: Meine benutzerdefinierte Klasse UITabViewController überschrieb viewWillAppear, ohne die Superimplementierung aufzurufen.

Verwandte Themen