2012-04-13 11 views
6

Muszę przejść do pierwszego widoku w mojej aplikacji. Mam kilka widoków wciśniętych na stos, potem modalny kontroler nawigacyjny i więcej widoków wciśniętych w to.Przejdź do kontrolera pierwszego widoku w aplikacji

Problem polega na tym, że użycie [[self navigationController] popToRootViewControllerAnimated:YES]; powraca tylko do pierwszego widoku stosu modalnego.

Nie mogę uzyskać [[self navigationController] popToViewController:.. do pracy, ponieważ prawdziwy kontroler pierwszego widoku nie jest dostępny z [[self navigationController] viewControllers].

Jakieś pomysły, jak to osiągnąć? Dzięki.

+0

Którego z nawigatorów dzwonisz do kontrolera? Zostanie on wyświetlony w katalogu głównym kontrolera nawigacyjnego o nazwie I imagine. –

+0

Utwórz pierwszy kontroler widoku jako rootViewcontroller kontrolera nawigacji –

+0

Zamknij kontroler widoku modalnego, a następnie przejdź do katalogu głównego. – Till

Odpowiedz

6

Wykonaj:

[[self navigationController] dismissModalViewControllerAnimated:YES]; 

To będzie powrót do VC że modally prezentowanym kontroler nawigacyjny. Dalsze oddalanie się po tym zależy od tego, jak popchnąłeś te "kilka widoków" przed kontrolerem nawigacyjnym.

Edit - wyjaśnienie dotrzeć do najgłębszych korzeni ...

Brzmi jak tych „kilku widokach” są na inny, będący podstawą stos kontrolera nawigacyjnego. Może to być trochę skomplikowane, ponieważ czystym sposobem, aby dostać się dalej z powrotem w tym stosie, jest poprowadzenie kontrolera nawigacyjnego do własnego katalogu głównego. Ale skąd może wiedzieć, że modalne VC na górze jest zrobione?

Zadzwonimy do kontrolera widoku, który wykonał modalną prezentację drugiego kontrolera nawigacyjnego VC_a. Jest to modalnie zaprezentowany kontroler nawigacyjny, którego najwyższym VC jest VC_b. W jaki sposób VC_a wie, aby uruchomić system nawigacyjny, gdy VC_b modalnie się od niego odrzuci?

Dobrą odpowiedzią (zazwyczaj) jest to, że VC_b zdecydował się z jakiegoś powodu odrzucić - jakiś warunek w aplikacji/modelu został zmieniony, aby zdecydować, że zostanie zrobione.

Chcemy, aby VC_a również wykrył ten warunek. Kiedy VC_b zostanie odwołany, a VC_a dostaje wiadomość viewWillAppear bo to ma być otwarty:

// VC_a.m 

- (void)viewWillAppear:(BOOL)animated { 

    [super viewWillAppear:animated]; 
    if (/* some app condition that's true when VC_b is done */) { 
     // I must be appearing because VC_b is done, and I'm being uncovered 
     // That means I'm done, too. So pop... 
     [self.navigationController popToRootViewControllerAnimated:NO]; 
    } else { 
     // I must be appearing for the normal reason, because I was just pushed onto the stack 
    } 
} 
+0

Mój problem polega na tym, że przed zwolnieniem kontrolera widoku modalnego mam brak odniesienia do widoku, który będzie na górze stosu, aby poinformować go o popToRoot. Wszystkie inne widoki przed pojedynczym widokiem modalnym były popychane za pomocą przełącznika wypychania za pomocą performSegueWithIdentifier, żaden z nich nie jest modalny. –

+0

Ale ten, który wykonał modalną prezentację drugiego kontrolera nawigacyjnego, wie, kim on jest. Ten będzie wiedział, że kontroler nawigacyjny zostanie zwolniony, gdy uzyska (drugi) viewWillAppear. Ten może się sam. Zobacz moją edycję. – danh

+0

Innymi słowy, osoba zwalniająca nie wie, kogo pop, i nie powinna. Prezentujący robi. – danh

0

Trzeba to zrobić za pomocą delegation pattern. W szczególności poprzez utworzenie protokołu implementującego metodę delegata: respondsToSelector.

Aby uzyskać szczegółowe informacje, patrz this post. Powinno to być prawie dokładnie to, czego szukasz. Musiałem zrobić coś podobnego, z wyjątkiem tego, że potrzebowałem tylko jednego widoku ze stosu nawigacji zamiast używać popToRootViewControllerAnimated:.

+0

to wygląda na to, że również będzie działać, mógłbym zaimplementować to szybciej z kodem z edycji powyższej odpowiedzi. w każdym razie dzięki –

0

W klasie AppDelegate.m stworzyć metodę z przepływu poniżej ...

-(void)MethodName{//your method name 
    YourViewController *objViewController = [[[YourViewController alloc] initWithNibName:@"YourViewController" bundle:nil] autorelease]; ///define your viewcontroller name like "FirstViewController" 
    UINavigationController *yourNavigationController = [[[UINavigationController alloc] initWithRootViewController:objViewController] autorelease]; 

    self.window.rootViewController = yourNavigationController; 
} 

Gdy chcesz przekierować na firstview tylko wywołać tę metodę z appdelegate obiektu ....

0

Dla iOS6 ...

[self.view.window.rootViewController dismissViewControllerAnimated:YES completion:nil]; 
Powiązane problemy