【问题标题】:ios navigation Stack Manipulationios导航栈操作
【发布时间】:2014-03-25 15:00:47
【问题描述】:

我在尝试从 ios 应用程序操作导航堆栈时遇到问题。或者至少是这种操纵导致的行为。

我的情况:

我有 3 个 ViewController。

控制器 a 显示多个级别, 控制器 b 是游戏视图 控制器 c 是某种分数

显然,我将在控制器 a 中选择一个关卡,这会触发对控制器 b 的转移,一旦关卡完成后将转移到控制器 c。每次转场都是一种推动。

现在,一旦我在控制器 c 中,我不希望能够使用后退按钮返回到 b。我想回到控制器a。为了让它工作,我从堆栈中删除了控制器,所以后面不会移动到控制器 b。这很好用。

我面临的问题是后退按钮确实显示在控制器 a 上,这似乎关闭了,因为不应该有任何后退。如果我点击后退按钮,应用程序不会崩溃,按钮会消失,留下标题。

我尝试添加:

    NSArray* controllers = [self.navigationController viewControllers];

    if ([controllers count]<=1) {
        [self.navigationItem setHidesBackButton:YES animated:YES];
    } else {
        [self.navigationItem setHidesBackButton:NO animated:YES];
    }
    [super viewDidAppear:animated];

正如一些相关的 stackoverflow 文章中所建议的那样,但没有成功。除了这不起作用之外,似乎 ios 在没有我实际添加它们的情况下从 Storyboard 创建这些按钮,但在不再需要它们时不会删除它们。这给我留下了一些选择。

  • 我认为 ios 比实际更智能
  • 我缺少更新导航栏所必需的东西
  • 我错了

besdies 我正在使用这段代码从控制器 b 到 c 进行剪切。

[self performSegueWithIdentifier:@"feedbackSegue" sender:self];
[self removeFromParentViewController];

非常感谢任何有关缺失操作或一般不良做法的提示。

更新

经过进一步调查,它不仅仅是后退按钮,整个导航栏都关闭了。它的行为就像被移除的控制器仍然在那里一样。 BackButton 在那里,右端有另一个 uiActionButton。

导航栏是否将其状态存储到与视图控制器不同的堆栈中?如果是这种情况,我也可以从该堆栈中删除该状态,以保持一致。

【问题讨论】:

    标签: ios objective-c uinavigationcontroller


    【解决方案1】:

    你可以在你的视图控制器中试试这个 c.这将删除以前的视图控制器,在您的情况下是 b。您还必须将 b 保留在堆栈中(删除 [self removeFromParentViewController]'; 行)

    -(void)viewDidAppear:(BOOL)animated{
        [super viewDidAppear:animated];
        if(self.navigationController.viewControllers.count>2){
            NSArray *controllers = self.navigationController.viewControllers;
            NSMutableArray *newViewControllers = [NSMutableArray arrayWithArray:controllers];
            [newViewControllers removeObject:[controllers objectAtIndex:self.navigationController.viewControllers.count - 2]];
            self.navigationController.viewControllers = newViewControllers;
        }
    }
    

    【讨论】:

    • 这就是我正在做的,导致同样的问题。问题不在于我实际上回到了控制器 b。即使无处可去,它的那个控制器仍然会显示出来
    • 好吧,我没有任何问题,不过请务必将其添加到 viewDidAppear 中。
    • 我在 viewdidload 中做了同样的事情。我不太清楚为什么它会有所作为,无论您是否删除了 didload 或 didappear 中的先前视图控制器(您能对此有所了解吗?),但显然它有所作为。谢谢。
    【解决方案2】:

    我相信“正确”的做法是移除控制器 c 上的后退按钮。根据移除控制器 b 的方式和时间,您可能会损坏导航控制器堆栈。操作视图控制器堆栈通常不是一个好习惯。

    要删除后退按钮,您有正确的代码:

    self.navigationItem.hidesBackButton = YES;
    

    但是,请注意,您必须在显示视图控制器之前调用它 - 即,在类似 viewDidLoad 的地方。

    当你想弹回 A 时,使用:

    [self.navigationController popToRootViewControllerAnimated:YES];
    

    【讨论】:

    • 如果我要隐藏后退按钮,我可以添加我自己的一个,然后触发 poptorootviewcontroller。它看起来没有什么不同,但在我看来,这是一个可行的选择。如果其他所有尝试都失败,我肯定会将此作为某种最终方法。谢谢,但我不确定这是一个好习惯。如果我做的事情也不好,那么实现所需控制器行为的正确方法是什么?
    • 看起来有一些方法可以设置您自己的自定义左栏按钮,该按钮的外观和行为就像您所描述的方式中的后退按钮。见:stackoverflow.com/questions/1214965/…
    • 但是,我认为真正的问题是,让后退按钮执行您所描述的操作会破坏导航控制器的流程 - 即您希望单击后退执行其他操作而不是让您返回到前一个视图控制器。我的建议是将弹出到根 vc 功能添加到后退按钮以外的其他内容。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-06
    • 2018-08-19
    • 2020-01-28
    • 1970-01-01
    相关资源
    最近更新 更多