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

Ios 在导航控制器中的视图之间跳转,ios,xcode,uinavigationcontroller,Ios,Xcode,Uinavigationcontroller,我需要在视图控制器之间切换。例如: View1: First screen (Just logo) View2: Download Screen View3: First app screen (Some Buttons) View4-View(N): some app screens 当用户进入应用程序时,应用程序进入View1->View2(下载内容)->View3->View4->View5 然后用户希望转到第一个应用程序屏幕(视图3),他执行以下操作: 用户第一次进入应用程序时会显示:

我需要在视图控制器之间切换。例如:

View1: First screen (Just logo)
View2: Download Screen
View3: First app screen (Some Buttons)
View4-View(N): some app screens
当用户进入应用程序时,应用程序进入View1->View2(下载内容)->View3->View4->View5 然后用户希望转到第一个应用程序屏幕(视图3),他执行以下操作:

用户第一次进入应用程序时会显示:View1->View3(不再需要下载屏幕),我有不同的推送顺序来转到View3,因此假设用户转到:View1->View3->View4->View5,现在他希望返回View3,因此功能:

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

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

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

  View3Controller view3Controller=[[View3Controller alloc]init];
 [self.navigationController popToViewController:@"view3Controller" animated:NO]
创建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]

在第二个序列中,您的导航堆栈将更改,view3将位于索引1处。所以

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

这是正确的做法。

如果您使用的是情节提要,那么您可以设置UIViewController的情节提要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成为导航控制器的
根视图控制器
,当您需要View1和view2
时,将它们显示为模式视图控制器

当你处理完它们,让我们说;用户已成功加载应用程序关闭徽标屏幕,并且
显示下载屏幕
如果下载成功,则关闭它

因此,您的View3将作为根视图控制器出现在那里,假设您的at视图(n)希望转到主屏幕,即View3,您只需调用

[self.navigationController popToRootViewControllerAnimated:NO];
当您在
view(n)
上并且想要弹出到
view(n-1)
时,只需使用

[self.navigationController popViewControllerAnimated:YES];

祝您好运,

听起来好像在运行时没有将视图2添加到视图控制器阵列中,可能是因为您创建的序列

根据应用程序的逻辑要求,尝试删除从“视图1”>“视图3”转换的序列,并将用户推过视图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];
或者,如果您将segue留在原位,您是否可以不查看
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

如果我理解正确,您的view3具有特殊的视图控制器,因此您可以使用以下代码:

NSArray *VCs = [self.navigationController viewControllers];
for (UIViewController *VC in VCs)
{
    if ([VC isKindOfClass:[**YOUR-VIEW-CONTROLLER** class]]) {
        [self.navigationController popToViewController:VC animated:NO];
    }
}

它很简单而且很有效

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

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

我总是用这个,它在你的情况下会很好的工作。事实上,以下代码行已复制到我的“备注”中,以便快速复制/粘贴

如果没有,请确保导入ViewController.h文件

for (UIViewController *viewController in self.navigationController.viewControllers) {
        if([viewController isKindOfClass:["your ViewController" class]]) {
            [self.navigationController popToViewController:viewController animated:NO];
        }
    }
for(self.navigationController.ViewController中的UIViewController*控制器){
if([controller iskindof class:[class]]){
[self.navigationController popToViewController:控制器已设置动画:是];
返回;
}
}

假设按顺序添加数组项,即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]动画:否];如果您想从不同的控制器或使用不同的堆栈结构返回到特定的控制器,请始终转到view3,无论您应该使用什么方式。我得到:不兼容的指针类型将“NSString*”发送到“UiviewController*”类型的参数@user1891408是否使用情节提要?替换为popToViewController:@”view3Controller”到popToViewController:view3Controller
for (UIViewController* controller in self.navigationController.viewControllers) {
        if ([controller isKindOfClass:[<Your View Controller Name> class]]) {
            [self.navigationController popToViewController:controller animated:YES];
            return;
        }
    }