在导航控制器中的视图之间跳转

Posted

技术标签:

【中文标题】在导航控制器中的视图之间跳转【英文标题】:Jumping between views in Navigation controller 【发布时间】:2013-02-21 15:16:37 【问题描述】:

我需要在视图控制器之间跳转。例如:

View1: First screen (Just logo)
View2: Download Screen
View3: First app screen (Some Buttons)
View4-View(N): some app screens

当用户进入应用程序时,应用程序转到 View1->View2(下载内容)->View 3->View4->View5 然后用户希望转到他所做的第一个应用程序屏幕(View3):

NSArray *array = [self.navigationController viewControllers];
[self.navigationController popToViewController:[array objectAtIndex:2] animated:NO];

用户第一次进入应用程序时:View1->View3(不再需要下载屏幕),我有不同的推送序列可以转到 View3,所以假设用户转到:View1->View 3- >View4->View5,现在他想回到View3,所以函数:

NSArray *array = [self.navigationController viewControllers];
[self.navigationController popToViewController:[array objectAtIndex:2] animated:NO];

会将他返回到 View4,这是错误的。我该如何解决?

【问题讨论】:

假设数组项按顺序添加 View1,View3,View4,View5 ,[array objectAtIndex:2] 应该给你 View4 这没什么错,[array objectAtIndex:0] = View1,[array objectAtIndex:1] = View3,[array objectAtIndex:2] = View4 这似乎是正确的我,试试下面的答案或试试objectAtIndex:1 错了我的意思是我需要函数 [self.navigationController popToViewController:[array objectAtIndex:2] animated:NO];无论如何,总是去view3 如果你想从不同的控制器或不同的堆栈结构返回到一个特定的控制器,你应该使用 unwind segue。 【参考方案1】:

如果你使用 storyboards ,你可以做的是设置你的 uiviewcontrollers 的 storyboard id 并使用它来弹出和推送你的视图。

假设您的故事板名称是MainStoryboard.storyboard

UIStoryboard*  sb = [UIStoryboard storyboardWithName:@"MainStoryboard"
                                                  bundle:nil];
SettingsListViewController *settingsVC = [sb instantiateViewControllerWithIdentifier:@"SettingsListViewController"]; // @"SettingsListViewController" is the string you have set in above picture
[self.navigationController popToViewController:settingsVC animated:YES];

上面的解决方案应该适合你,但如果我是你,我会改变我的应用程序的结构,你说:

View1: First screen (Just logo)
View2: Download Screen

由于 View1 只是徽标,而 View 2 也是您可以跳过的视图,因此您可以将它们从导航控制器中删除,并将 View3 设为导航控制器的 root view controller,当您需要 view1 和 view2 present them as Modal View Controllers 时,

当你完成它们时,让我们说;用户成功加载应用程序关闭徽标屏幕,present Download Screen 如果下载成功则关闭它。

所以您的 View3 将作为根视图控制器存在,假设您在 View(n) 处想要转到 View3 的主屏幕,您需要做的就是调用

[self.navigationController popToRootViewControllerAnimated:NO];

当您在view(n) 并想弹出到view(n-1) 时,只需使用

[self.navigationController popViewControllerAnimated:YES];

祝你好运,

【讨论】:

【参考方案2】:

在第二个序列中,您的导航堆栈发生变化,view3 将位于索引 1。所以

[[self.navigationController popToViewController:[array objectAtIndex:1] animated:NO];

这将是正确的做法。

【讨论】:

【参考方案3】:

根据您的情况直接使用 viewController 的名称

创建你的 viewController 的实例,像这样 我在这里假设您的 viewController 名称是-view3Controller

  View3Controller view3Controller=[[View3Controller alloc]init];
 [self.navigationController popToViewController:@"view3Controller" animated:NO]

或者如果你使用的是故事板,那么

View3Controller view3Controller=[self.storyboard instantiateViewControllerWithIdentifier:@"view3Controller"];

        [self.navigationController popToViewController:@"view3Controller" animated:NO]

【讨论】:

我得到:不兼容的指针类型将“NSString *”发送到“UiviewController *”类型的参数 @user1891408 你使用故事板吗? 替换 popToViewController:@"view3Controller" 为 popToViewController:view3Controller【参考方案4】:

听起来 View 2 没有在运行时添加到您的视图控制器数组中,可能是因为您创建了 segue。

尝试删除从 View 1 > View 3 转换的 segue 并将用户推过 View 2 而无需动画,因为您的应用程序的逻辑需要它:

// If the user needs to skip ahead to view 3, conditionally push view 2 and view 3 without animating
[self.navigationController pushViewController:viewController2 animated:NO];
[self.navigationController pushViewController:viewController3 animated:NO];

或者,如果您将转场留在原地,您是否可以不查看 UINavigationController viewControllers 属性的大小并根据您是否跳过视图 2 的大小“猜测”?如果你这样做了,那么你可以调整popToViewController 方法以弹出正确的索引。如果您还需要跳过其他视图,这无疑是不那么优雅和脆弱的。

// Check length of viewController array with 'N' views (pseudo code)
if (self.navigationController.viewControllers.length == N-1)
    // View 2 was ignored: pop to objectAtIndex:1
else 
    // View 2 was included: pop to objectAtIndex:2

【讨论】:

【参考方案5】:

如果我理解正确的话,你的 view3 有特殊的视图控制器,所以你可以使用这样的代码:

NSArray *VCs = [self.navigationController viewControllers];
for (UIViewController *VC in VCs)

    if ([VC isKindOfClass:[**YOUR-VIEW-CONTROLLER** class]]) 
        [self.navigationController popToViewController:VC animated:NO];
    

这很简单,而且很有效!

【讨论】:

【参考方案6】:

我总是使用这个,它在你的情况下可以正常工作。事实上,以下代码行被复制到我的“Notes”中以便快速复制/粘贴。

如果没有,请务必导入您的 ViewController.h 文件。

for (UIViewController *viewController in self.navigationController.viewControllers) 
        if([viewController isKindOfClass:["your ViewController" class]]) 
            [self.navigationController popToViewController:viewController animated:NO];
        
    

【讨论】:

【参考方案7】:
for (UIViewController* controller in self.navigationController.viewControllers) 
        if ([controller isKindOfClass:[<Your View Controller Name> class]]) 
            [self.navigationController popToViewController:controller animated:YES];
            return;
        
    

【讨论】:

【参考方案8】:

像这样转到特定的视图控制器

  [self.navigationController popToViewController:[[self.navigationController viewControllers]objectAtIndex:1] animated:YES];

【讨论】:

以上是关于在导航控制器中的视图之间跳转的主要内容,如果未能解决你的问题,请参考以下文章

在导航控制器中的视图之间跳转

Xcode常见快捷键

jquery页面跳转导航变色,刷新后依然存在

微信小程序中tabBar与导航API的页面跳转处理关系

在不同导航控制器中的视图之间切换

如何在 swiftui 中的按钮操作上在视图控制器之间导航?