iOS视图控制器导航路径 - 如何通过编程方式返回导航。

4

我正在使用IOS5故事板。我的视图控制器路径如下:

tabbarVC --> navigationVC-1 --> tableVC-1 --(via segue push)-> tableVC-2 --(via segue modal)-> navigationVC-2 --> tableVC-3

在tableVC-3中的取消按钮回调方法中,我调用[self dismissViewControllerAnimated:YES completion:nil];成功返回到了tableVC-2。但是,当我尝试在调试器中向后检查导航路径时,我没有看到从navigationVC-2访问tableVC-2的方法。我期望navigationVC-2保持与tableVC-2或navigationVC-1的链接,但似乎并没有。请参见下面我的调试器输出。
有人能解释一下导航层次结构以及如何以编程方式遍历链吗?
(gdb) po self
<tableVC-3: 0x6d33340>

(gdb) po (UIViewController*) [self navigationController]
<UINavigationController: 0x6d33560>

(gdb) po (UIViewController*)[[self navigationController] navigationController]
Can't print the description of a NIL object.

(gdb) po (UIViewController*)[[self navigationController] topViewController]
<tableVC-3: 0x6d33340>

(gdb) po (UIViewController*)[[self navigationController] presentingViewController]
<UITabBarController: 0x6b2eba0>

(gdb) po (UIViewController*)[[self navigationController] presentedViewController]
Can't print the description of a NIL object.

(gdb) po (UIViewController*)[[self navigationController] visibleViewController]
<tableVC-3: 0x6d33340>
4个回答

8
这是一个老问题,但为了帮助其他遇到这个问题的人,有一个命令可以让你的生活更轻松。请使用一个命令即可。
[self.navigationController popToRootViewControllerAnimated:TRUE];

当你遇到正确的命令时,事情就变得容易了,不是吗!

假设你在导航控制器中有三个屏幕,并且在第三个屏幕上,你希望“返回”按钮将你带回到初始屏幕。

-(void)viewDidLoad
{
    [super viewDidLoad];

    // change the back button and add an event handler
    self.navigationItem.leftBarButtonItem =
    [[UIBarButtonItem alloc] initWithTitle:@"Back"
                                     style:UIBarButtonItemStyleBordered
                                    target:self
                                    action:@selector(handleBack:)];
}


-(void)handleBack:(id)sender
{
    NSLog(@"About to go back to the first screen..");
    [self.navigationController popToRootViewControllerAnimated:TRUE];
}

4

在使用此方法以及其他一些用于故事版中模态UIViewControllers退回两个视图的问题进行研究后,我使用了以下代码:

[self.presentingViewController.presentingViewController dismissViewControllerAnimated:YES completion:nil];

这个评论让我尝试了[self.navigationController.navigationController popToRootViewControllerAnimated:YES];。结构是这样的:导航控制器->表视图->(通过推送segue)->导航控制器->视图控制器。这对我起作用了!此外,它让我深入了解了事物的运作方式。 - joker

4

需要更新旧的响应内容以使其更完整。
回答这个问题:

可以有人解释导航层次结构以及如何以编程方式遍历链条吗?

你的导航结构如下:

tabbarVC --> navigationVC-1 --> tableVC-1 --(通过segue push)-> tableVC-2 --(通过segue modal)-> navigationVC-2 --> tableVC-3

可以这样解释:
TabbarVC显示它的“selectedViewController”(navigationVC-1)。
NavigationVC-1具有由TableVC-1和TableVC-2组成的导航堆栈(NavigagtionVC-1的topViewController)。
然后,navigationVC-2以modal的形式呈现在tabbarVC之上,因此tabbarVC是presentingViewController,而navigationVC-2是presentedViewController

因此,要从tableVC-3到达tableVC-2,您需要执行以下操作:

[(UINavigationController *)[(UITabBarController *)[tableVC-3 presentingViewController] selectedViewController] topViewController];

(不要在生产代码中这样做)

[tableVC-3 presentingViewController] 以及 [tableVC-3.navigationController presentingViewController] 将返回 UITabBarController


如果你正在使用 UINavigationController,应该使用它的 pushpop 方法将 UIViewController 放入或移出“presentation stack”(展示栈)。
你可以像这样从这些 UIViewController 中访问 UINavigationController

self.navigationController

如果您想返回超过一个“展示堆栈”中的UIViewController,可以使用UINavigationController上的此方法

popToViewController:animated:
弹出视图控制器,直到指定的视图控制器位于导航堆栈的顶部。
- (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated


要关闭以模态方式呈现的UIViewController,需要使用呈现它的UIViewController来关闭它:
- (void)dismissModalViewControllerAnimated:(BOOL)animated

所以在这种情况下,应该是:
[tableVC-2 dismissModalViewControllerAnimated:YES];

实际上我的问题不同。请注意我有2个导航控制器正在使用中。我的问题是如何返回到第一个导航控制器。如果你看到我贴出的调试输出,似乎没有任何方法可以回到第一个导航控制器。 - mpprdev
感谢您的评论。没有第二个导航控制器,“模态”类型的转场似乎无法正常工作(应用程序崩溃)。 - mpprdev
@mpprdev - 好的,我明白了,我对segue不太熟悉。你不想返回,而是想关闭你的模态展示。 - Vincent Bernier
不是与问题相关,但谢谢,我一直在寻找pop函数,但没有找到导航控制器(一直在父控制器中查找...现在一切都有意义了。 - Jason Rogers
一个小提示:如果你想返回到以前的视图,而不传递它作为参数,只需使用以下代码:[[self navigationController] popViewControllerAnimated:YES]; - pAkY88

0

Swift

如果您正在使用导航控制器,则可以通过以下方式导航回上一个视图控制器:

self.navigationController?.popViewControllerAnimated(true)

或返回到根视图控制器
self.navigationController?.popToRootViewControllerAnimated(true)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接