7

Jako przegląd mam problemy z UINavigationController wewnątrz widoku wywołującego UITabBarController ViewWillAppear za każdym razem, gdy widok jest wyskakiwany ze stosu.Problemy z UINavigationController wewnątrz UITabBarController, viewWillAppear nie nazywane

Od delegata, A UITabBarController jest programowo:

// 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]; 

Moja newsFeedNavigationController jest tylko podklasy UITableViewController (i podklasa nie zakłóca viewWillAppear, ponieważ nigdy się nazywa w newsFeedNavigationController). W nim elementy, które po kliknięciu popchną nowy UIViewController do stosu.

Problem polega na tym, że za każdym razem, gdy widoki są wyskakiwane ze stosu, viewWillAppear nigdy nie jest wywoływane w newsFeedNavigationController, a elementy na liście pozostają podświetlone. Robiłem sobie z tym problem przez kilka godzin w punkcie, w którym potrzebuję pomocy, aby dowiedzieć się, co robię źle.

W moim newsFeedNavigationController, próbowałem dodać NSLog, aby zobaczyć, czy jest on wywoływany lub zrobiłem coś, ale nigdy nie jest nawet wywoływany.

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

Edit:

Dobra, tu jest coś dziwnego zauważyłem:

Jeśli biegnę:

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

a następnie jej oddalenie, viewWillAppear zaczyna działać poprawnie kiedy wyskakuje i popycha widoki ... Więc teraz jestem zaskoczony. To naprawdę nie jest rozwiązanie, ale może coś z tego, co się dzieje.

Odpowiedz

1

Aby odpowiedzieć na własne pytanie, dowiedziałem się, na czym polega problem.

W celu przestrzegania przez Apple „Nie UITabBarController wewnątrz UINavigationController” Napisałem mój własny kontroler tab bar (bookTabBarController), który jest oparty off widoku standardowego kontrolera. Mój problem polegał na tym, że klasa nie przekazywała viewDidAppear do klasy, która zarządzała kontrolerami widoku, więc nigdy nie wiedziała, że ​​jest pokazywana, czy nie.

+0

Jestem zdezorientowany. W swoim wpisie powiedziałeś "UINavigationController wewnątrz kontrolera UITabBarController", a podczas Twojego działania powiedziałeś "UITabBarController wewnątrz kontrolera UINavigationController" ... który? Ponieważ mam identyczny problem z kontrolerem Nav jako kartą w kontrolerze paska kart ... który, jak rozumiem, powinien być obsługiwany. Ale ViewDidAppear zaczyna działać dopiero po przedstawieniu widoku modalnego z jednego z widoków przekazanych do kontrolera nawigacyjnego. Bardzo dziwny. – Steve

+0

Zobacz moją odpowiedź na ogólne rozwiązanie tego problemu. – titaniumdecoy

+0

To było tak samo jak mój problem. Przepraszam za zamieszanie. To, co początkowo miałem, to kontroler UINavigationController z kontrolerem widoku, a następnie ekran "home" zawierałby w zasadzie to, co zasadniczo było kontrolerem UITabBarController w stosie. Następnie możesz wrzucić nowy widok do stosu. Np. UINavigationController z widokiem logowania jako root, po wejściu na platformę uitabbar, a widoki z tabeli można wepchnąć do "głównego" nav. Mój problem polegał na tym, że viewWillAppear nie był przekazywany na stos (przechodziłby od UINavigationController do UITabBarController, ale nie do widoku paska zakładek). – Dandy

1

Kolejnym rozwiązaniem jest ustawienie kontrolera nawigacyjnego. W ramach delegata, wdrożyć następujące metody:

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

To zapewni, że viewWillAppear zostanie sprawdzony na dowolnym kontrolerze widoku, którego widok ma się pojawić w kontroler nawigacji. Jeśli robisz to w ten sposób, wywoływana jest viewWillAppear niezależnie od tego, czy widok jest wyświetlany, ponieważ jest on pchany, czy też pojawia się, ponieważ wyskakuje podgląd.

+0

Niestety, wypróbowałem tę metodę i nie zadziałało. Cóż, zadziałało, ale tak się nie stało. Problem polegał na tym, że pomimo wywołania funkcji viewWillAppear: animated, nie była ona przekazywana do podglądu zawartego na pasku kart, ponieważ nie była ona wywoływana jawnie w widoku paska zakładekWillAppear. Jednak w przypadku innych osób napotykających problemy, jest to potencjalne rozwiązanie. Jednak jeśli viewWillAppear: animated nie działa, prawdopodobnie oznacza to, że coś innego jest nie tak (jak w moim przypadku). – Dandy

1

Rozwiązaniem tego problemu jest sprawdzenie, czy kontroler UIViewController zawierający kontroler UINavigationController przekazuje do niego pożądane komunikaty. UINavigationController przekaże wiadomości do odpowiedniego kontrolera widoku. Wydaje się sprzeczne z intuicją, ale działa.

@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

Możesz znaleźć bardziej kompletne rozwiązanie na Pastebin (którego nie napisałem).

Podziękowania dla davidbenini.it i jaekwon za to rozwiązanie.

+0

To rozwiązanie jest nieco niekompletne, a link do wklejania jest nieco syntaktycznym bałaganem, ale niech mnie diabli, jeśli to nie rozwiąże mojego problemu! Rządzisz! –

1

Jeszcze prostsze trick:

W swojej podklasy UITabBarController, zastąpić to:

-(void)loadView{ 

    [super loadView]; 

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

Ta praca pomogła mi, ale okazało się, że ustawienie indeksu z powrotem na 0 natychmiast nie działa. Musiałem czekać do viewDidAppear. Druga strona nie wyświetla się ani nie migocze i działa z niespodzianką, ponieważ ręczne wybranie innej karty początkowo oznaczało, że problematyczny widok będzie działał. Jedno zastrzeżenie to to, że indeks, na który go ustawiłeś, musi zawierać bardzo prostą stronę. Pierwotnie wypróbowałem widok z podrzędnym widokiem, a podrzędny widok zniknął, ale nadal może zająć interakcję użytkownika, tj. Problem został zamiast tego przesunięty na tę kartę. – RowanPD

0

OK, to jest stary, bardzo stary, ale skończyło się tutaj z podobnym problemem.

UITabViewController 
    UINavigationController 
     UITableViewController1 
     UITableViewController2 

Gdy wychodziły z UITableViewController2 funkcja w UITableViewController1viewWillAppear nigdy nie został powołany.

Problem: Moja niestandardowa klasa UITabViewController przesłaniała numer viewWillAppear bez wywoływania superprogramowania.

Powiązane problemy