Objective c NavigationController返回跳过视图

Objective c NavigationController返回跳过视图,objective-c,ios,uinavigationcontroller,Objective C,Ios,Uinavigationcontroller,首先,我知道这个问题是以向前的方式提出的,但在这种情况下,我要求的是导航控制器已经设计好的向后的方式。话虽如此 我有一个带有三个视图的UINavigationController,Get和Avail,它们的顺序与IB中创建的顺序相同 前进时,我想从Table转到Get到Avail,但当我点击Avail上的“后退”按钮时,我想跳过Get,直接回到Table。这可能吗?如果是这样,怎么做?看看-popToViewController:animated:和-popToRootViewControlle

首先,我知道这个问题是以向前的方式提出的,但在这种情况下,我要求的是导航控制器已经设计好的向后的方式。话虽如此

我有一个带有三个视图的
UINavigationController
Get
Avail
,它们的顺序与IB中创建的顺序相同

前进时,我想从
Table
转到
Get
Avail
,但当我点击
Avail
上的“后退”按钮时,我想跳过
Get
,直接回到
Table
。这可能吗?如果是这样,怎么做?

看看
-popToViewController:animated:
-popToRootViewControllerAnimated:
,它们完全满足了您的要求。也就是说,它们将导航堆栈弹出回特定的视图控制器或根视图控制器。不过,您仍然需要拦截导航控制器的后退按钮操作才能使用它们。

请查看
-popToViewController:animated:
-poptrootviewcontrolleranimated:
,它们完全满足您的要求。也就是说,它们将导航堆栈弹出回特定的视图控制器或根视图控制器。不过,您仍然需要截获导航控制器的后退按钮操作才能使用它们。

我是这样做的:

NSArray *VCs = [self.navigationController viewControllers];
[self.navigationController popToViewController:[VCs objectAtIndex:([VCs count] - 2)] animated:YES];
为了能够覆盖导航控制器的后退按钮,您必须子类UINavigationController。查看本教程中的操作方法:

以下是我的操作方法:

NSArray *VCs = [self.navigationController viewControllers];
[self.navigationController popToViewController:[VCs objectAtIndex:([VCs count] - 2)] animated:YES];

为了能够覆盖导航控制器的后退按钮,您必须子类UINavigationController。查看本教程中的方法:

如何实现导航控制器的委托方法:

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
//Remove list setup page if new list was created
if ([self.navigationController topViewController].class == [ItemViewController class])
{
    NSArray *VCs = [self.navigationController viewControllers];

    if(((UITableViewController*)[VCs objectAtIndex:[VCs count]-2]).class == [NewCardTypeController class])
    {
        NewCardTypeController *removedObject = [VCs objectAtIndex:[VCs count]-2];
        if(removedObject != nil)
        {
            NSMutableArray *newArray = [NSMutableArray arrayWithArray:VCs];
            [newArray removeObject:removedObject];
            NSArray *newVCs = [NSArray arrayWithArray:newArray];
            [self.navigationController setViewControllers:newVCs animated:NO];
        }
    }
}
它将为导航控制器堆栈中的所有VCs点火。(将此代码立即放在导航控制器之后的VC中,并将<
UINavigationControllerDelegate
>放在
.h
中)

您要做的是替换整个导航控制器的堆栈,而不替换要在其中删除的视图控制器。由于它是一个不可变数组,您必须在移除VC之前将其转换为可变数组,移除VC,然后用调用替换导航控制器的堆栈
[self.navigationController setViewControllers:newVCs animated:NO]。这是关键部分。加载页面后,您将替换堆栈,但由于您保留了所在的VC,因此它仍然是堆栈的顶部项目,因此对用户没有明显影响。只要你没有太多的风险投资,这不是一个昂贵的电话

下面是我在委托方法中的操作:

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
//Remove list setup page if new list was created
if ([self.navigationController topViewController].class == [ItemViewController class])
{
    NSArray *VCs = [self.navigationController viewControllers];

    if(((UITableViewController*)[VCs objectAtIndex:[VCs count]-2]).class == [NewCardTypeController class])
    {
        NewCardTypeController *removedObject = [VCs objectAtIndex:[VCs count]-2];
        if(removedObject != nil)
        {
            NSMutableArray *newArray = [NSMutableArray arrayWithArray:VCs];
            [newArray removeObject:removedObject];
            NSArray *newVCs = [NSArray arrayWithArray:newArray];
            [self.navigationController setViewControllers:newVCs animated:NO];
        }
    }
}

实现导航控制器的委托方法:

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
//Remove list setup page if new list was created
if ([self.navigationController topViewController].class == [ItemViewController class])
{
    NSArray *VCs = [self.navigationController viewControllers];

    if(((UITableViewController*)[VCs objectAtIndex:[VCs count]-2]).class == [NewCardTypeController class])
    {
        NewCardTypeController *removedObject = [VCs objectAtIndex:[VCs count]-2];
        if(removedObject != nil)
        {
            NSMutableArray *newArray = [NSMutableArray arrayWithArray:VCs];
            [newArray removeObject:removedObject];
            NSArray *newVCs = [NSArray arrayWithArray:newArray];
            [self.navigationController setViewControllers:newVCs animated:NO];
        }
    }
}
它将为导航控制器堆栈中的所有VCs点火。(将此代码立即放在导航控制器之后的VC中,并将<
UINavigationControllerDelegate
>放在
.h
中)

您要做的是替换整个导航控制器的堆栈,而不替换要在其中删除的视图控制器。由于它是一个不可变数组,您必须在移除VC之前将其转换为可变数组,移除VC,然后用调用替换导航控制器的堆栈
[self.navigationController setViewControllers:newVCs animated:NO]。这是关键部分。加载页面后,您将替换堆栈,但由于您保留了所在的VC,因此它仍然是堆栈的顶部项目,因此对用户没有明显影响。只要你没有太多的风险投资,这不是一个昂贵的电话

下面是我在委托方法中的操作:

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
//Remove list setup page if new list was created
if ([self.navigationController topViewController].class == [ItemViewController class])
{
    NSArray *VCs = [self.navigationController viewControllers];

    if(((UITableViewController*)[VCs objectAtIndex:[VCs count]-2]).class == [NewCardTypeController class])
    {
        NewCardTypeController *removedObject = [VCs objectAtIndex:[VCs count]-2];
        if(removedObject != nil)
        {
            NSMutableArray *newArray = [NSMutableArray arrayWithArray:VCs];
            [newArray removeObject:removedObject];
            NSArray *newVCs = [NSArray arrayWithArray:newArray];
            [self.navigationController setViewControllers:newVCs animated:NO];
        }
    }
}

顺便说一句,这样做,其他答案不会做的是保留正确的导航栏序列,并确保“后退”按钮在转换时具有正确的动画行为,因为您没有覆盖它。顺便说一下,这样做,其他答案不会做的是保留正确的导航栏序列,并确保您的后退按钮在转换时具有正确的动画行为,因为您没有覆盖它。然后突然有人(甚至您)更新您的项目,并将新的VCs移除或添加到导航控制器堆栈中。而且您的代码将无法工作(在最佳情况下)。神奇的数字总是邪恶的。然后突然有人(甚至你们)更新你们的项目,删除或添加新的VCs到导航控制器堆栈中。而且您的代码将无法工作(在最佳情况下)。神奇的数字总是邪恶的。