2011-12-24 68 views
23

我有一個iPhone應用程序,它使用UINavigationController的標準實現進行應用程序導航。在UINavigationController層次結構中替換UIViewController

我想找出一種方法來替換層次結構中的視圖控制器。 換句話說,我的應用程序加載到rootViewController,當用戶按下按鈕時,應用程序將推送到firstViewController。然後用戶按另一個按鈕導航應用程序secondViewController。再次使用導航到另一個視圖控制器thirdViewController。但是,我想讓thirdViewController的BackButton回彈到firstViewController。

本質上,當用戶推到thirdViewController時,我希望它在導航層次結構中替換secondViewController

這可能嗎?我知道它使用Three20,但我不是在這種情況下。儘管如此,如果在Three20中有可能,那麼它肯定應該使用直接的SDK調用。有人有想法嗎?

乾杯, 佈雷特

+0

我還要考慮放鬆身心塞格斯,他們爲實現這種東西是有用的。真棒所以回答他們在這裏:http://stackoverflow.com/questions/12561735/what-are-unwind-segues-for-and-how-do-you-use-them – jrisberg 2015-07-07 20:26:54

+0

在給出的例子中,不是嗎?簡單地彈出(這將擺脫第二個),然後推(你現在有1-3)。或者,如果它是一個「不同的按鈕」,當你在1-2-3上時,只需彈出兩次,你就會打開1. – Fattie 2018-01-05 00:11:32

回答

41

很簡單,當即將推thirdViewController,而不是做一個簡單的pushViewController做到這一點:

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

其中[viewControllers objectAtIndex:0][viewControllers objectAtIndex:1]是你的RootViewController的和你FirstViewController。

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

更多信息,請參見UINavigationController class reference

+0

謝謝,夥伴。該解決方案處理它。乾杯。 – Felipe 2016-05-03 13:39:04

4

如果您只是替換導航控制器視圖控制器陣列中的viewController,則無法對轉換進行動畫處理。我建議在第三個視圖控制器的viewWillAppear方法中執行以下操作。

-(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

既然你只是試圖從ViewControllers兩次彈出堆棧,你也許可以通過的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

後退按鈕調用

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

得到相同的結果Swift 2.2版本:

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

斯威夫特一個更清潔的方式應該是:

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

不會刪除所有的人,只留下一個? – Fattie 2018-01-04 20:51:13

+0

@Fattie是的。這對於OP場景就足夠了。該函數設置頂部viewController。如果你不想要這種行爲,那麼你需要一個不同的功能。 – Harris 2018-01-05 22:14:54

+1

瞭解。好東西。 – Fattie 2018-01-06 01:39:00