2011-12-24 40 views
23

Tôi có một ứng dụng iPhone sử dụng cài đặt chuẩn của UINavigationController cho điều hướng ứng dụng.Thay thế UIViewController trong hệ thống phân cấp UINavigationController

Tôi đang cố gắng tìm ra cách thay thế bộ điều khiển chế độ xem trong cấu trúc phân cấp. Nói cách khác, ứng dụng của tôi tải vào một số rootViewController và khi người dùng nhấn một nút, ứng dụng sẽ đẩy tới firstViewController. Sau đó, người dùng đẩy một nút khác để điều hướng ứng dụng đến secondViewController. Một lần nữa việc sử dụng điều hướng xuống một bộ điều khiển khung nhìn khác, thirdViewController. Tuy nhiên, tôi muốn BackButton của thirdViewController để bật trở lại firstViewController.

Về cơ bản, khi người dùng đẩy đến thirdViewController, tôi muốn thay thế secondViewController trong hệ thống phân cấp điều hướng.

Điều này có khả thi không? Tôi biết nó đang sử dụng Three20, nhưng tôi không phải trong trường hợp này. Tuy nhiên, nếu có thể trong Three20, thì chắc chắn nó sẽ sử dụng các cuộc gọi SDK thẳng. Có ai có suy nghĩ gì không?

Chúc mừng, Brett

+0

tôi cũng sẽ nhìn vào Thư giãn Segues, họ đang có ích cho việc hoàn thành loại điều. Câu trả lời SO tuyệt vời trên chúng tại đây: http://stackoverflow.com/questions/12561735/what-are-unwind-segues-for-and-how-do-you-use-them – jrisberg

+0

Trong ví dụ đã cho, bạn sẽ không chỉ đơn giản là bật (mà sẽ thoát khỏi thứ hai), và sau đó đẩy (bây giờ bạn có 1-3). Cách khác, nếu đó là "nút khác", khi bạn đang ở trên 1-2-3, chỉ cần bật hai lần và bạn sẽ ở trên 1. – Fattie

Trả lời

41

Khá đơn giản, khi sắp đẩy thirdViewController thay vì làm một đơn giản pushViewController làm điều này:

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

nơi [viewControllers objectAtIndex:0][viewControllers objectAtIndex:1] là rootViewController của bạn và FirstViewController của bạn.

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

Xem UINavigationController class reference để biết thêm thông tin.

+0

Cảm ơn, bạn đời. Giải pháp này xử lý nó. Chúc mừng. – Felipe

4

Không thể tạo hiệu ứng chuyển tiếp nếu bạn chỉ cần thay thế viewController trong mảng bộ điều khiển xem bộ điều khiển điều hướng. Tôi sẽ khuyên bạn nên làm như sau trong phương pháp viewWillAppear của bộ điều khiển xem thứ ba.

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

Vì bạn đang cố gắng để bật hai lần từ ViewControllers chồng, có lẽ bạn có thể nhận được kết quả tương tự bằng cách gọi

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

từ nút quay lại của 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

Phiên bản Swift 2.2:

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

Một cách sạch hơn trong Swift nên là:

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

sẽ không loại bỏ tất cả chúng, và chỉ để lại một? – Fattie

+0

@Fattie yep. Điều đó đủ cho kịch bản OP. Hàm này thiết lập viewController trên cùng. Nếu bạn không muốn hành vi đó, thì bạn sẽ cần một chức năng khác. – Harris

+1

Đã hiểu. dụng cụ tốt. – Fattie

Các vấn đề liên quan