2011-12-24 13 views
23

Mam aplikację na iPhone'a, która używa standardowej implementacji UINavigationController do nawigacji w aplikacji.Zamień UIViewController w hierarchii UINavigationController

Próbuję znaleźć sposób zastąpienia kontrolera widoku w hierarchii. Innymi słowy, moja aplikacja ładuje się do rootViewController, a gdy użytkownik naciśnie przycisk, aplikacja przesuwa się do firstViewController. Następnie użytkownik naciska inny przycisk, aby nawigować po aplikacji pod numerem secondViewController. Ponownie użycie przechodzi do innego kontrolera widoku, thirdViewController. Jednak chcę BackButton z thirdViewController, aby wrócić do firstViewController.

Zasadniczo, gdy użytkownik przesyła do thirdViewController, chciałbym, aby zastąpił on secondViewController w hierarchii nawigacji.

Czy to możliwe? Wiem, że używa on Three20, ale nie jestem w tym przypadku. Niemniej jednak, jeśli jest to możliwe w Three20, to z pewnością powinno się używać prostych wywołań SDK. Czy ktoś ma jakieś myśli?

Cheers, Brett

+0

Chciałbym również przyjrzeć się odprężyć segues, są one przydatne do realizacji tego rodzaju rzeczy. Niesamowita odpowiedź SO na ich temat: http://stackoverflow.com/questions/12561735/what-are-unwind-segues-for-and-how-do-you-use-them – jrisberg

+0

W podanym przykładzie, czy nie po prostu pop (to pozbędzie się drugiego), a następnie naciśnij (masz teraz 1-3). Alternatywnie, jeśli jest to "inny przycisk", gdy jesteś na 1-2-3, po prostu pop dwa razy i będziesz na 1. – Fattie

Odpowiedz

41

Całkiem proste, kiedy o pchnąć thirdViewController zamiast robić proste pushViewController to zrobić:

NSArray * viewControllers = [self.navigationController viewControllers]; 
NSArray * newViewControllers = [NSArray arrayWithObjects:[viewControllers objectAtIndex:0], [viewControllers objectAtIndex:1], thirdController,nil]; 
[self.navigationController setViewControllers:newViewControllers]; 

gdzie [viewControllers objectAtIndex:0] i [viewControllers objectAtIndex:1] są twoje rootViewController a FirstViewController.

22
NSMutableArray *viewController = [NSMutableArray arrayWithArray:[navController viewControllers]]; 
[viewController replaceObjectAtIndex:1 withObject:replacementController]; 
[navController setViewControllers:viewController]; 

Zobacz UINavigationController class reference aby uzyskać więcej informacji.

+0

Dzięki, stary. To rozwiązanie poradziło sobie z tym. Twoje zdrowie. – Felipe

4

Animacja przejścia nie jest możliwa, jeśli po prostu zastąpisz viewController w tablicy kontrolerów kontrolek nawigacyjnych. Zalecam wykonanie następujących czynności w metodzie viewWillAppear trzeciego kontrolera widoku.

-(void) viewWillAppear:(BOOL)animated 
{ 
    NSArray *vCs=[[self navigationController] viewControllers]; 
    NSMutableArray *nvCs=nil; 
    //remove the view controller before the current view controller 
    nvCs=[[NSMutableArray alloc]initWithArray:vCs]; 
    [nvCs removeObjectAtIndex:([nvCs count]-2)]; 
    [[self navigationController] setViewControllers:nvCs]; 
    [super viewWillAppear:animated]; 
} 
2

Ponieważ jesteś po prostu staramy się pop dwukrotnie z ViewControllers stos, prawdopodobnie można uzyskać ten sam rezultat poprzez wywołanie

- (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated 

z tylnym przyciskiem thirdViewController

1
- (void)swapTopViewController:(UIViewController *)topViewController{ 
    NSArray *viewControllers = [self.navigationController viewControllers]; 
    NSMutableArray *editableViewControllers = [NSMutableArray arrayWithArray:viewControllers]; 
    [editableViewControllers removeLastObject]; 
    [editableViewControllers addObject:topViewController]; 
    [self.navigationController setViewControllers:editableViewControllers]; 
} 
0

Wersja Swift 2.2:

if var viewControllers = navigationController?.viewControllers { 
    viewControllers[viewControllers.count - 1] = newViewController 
    navigationController?.viewControllers = viewControllers 
} 
2

Czystsze sposób Swift powinno być:

extension UINavigationController { 
    func replaceTopViewController(with viewController: UIViewController, animated: Bool) { 
    var vcs = viewControllers 
    vcs[vcs.count - 1] = viewController 
    setViewControllers(vcs, animated: animated) 
    } 
} 
1
extension UINavigationController { 

    func setTop(viewController: UIViewController) { 
     viewControllers = [viewController] 
    } 

} 
+0

czy to nie usunie ich wszystkich i pozostawi tylko jedną? – Fattie

+0

@ Fattie yep. Co wystarczy w scenariuszu PO. Ta funkcja ustawia widok z góry kontrolera. Jeśli nie chcesz tego zachowania, potrzebujesz innej funkcji. – Harris

+1

Zrozumiano. miłe rzeczy. – Fattie

Powiązane problemy