【问题标题】:UINavigationController setViewController:animated: navigation bar difficultiesUINavigationController setViewController:animated: 导航栏困难
【发布时间】:2011-01-01 21:32:20
【问题描述】:

我遇到了一个令人难以置信的令人沮丧的问题,似乎是一个错误,但我很难相信没有其他人遇到过这个问题。我的应用程序的根视图控制器是一个 UITabBarController,其中每个选项卡都是一个 UINavigationController。一切都很好。

现在到了要编辑栈的地方,所以我重新排列了当前导航控制器的viewControllers然后做:

[self.navigationController setViewControllers:newViewControllers animated:YES];

堆栈已正确弹出/推送到顶部视图控制器,但导航栏不会更新到当前视图控制器,并且似乎与弹出前的 viewController 完全相同。如果我这样做:

[self.navigationController popToViewController:someViewController animated:YES];

一切都很完美。有没有人遇到过这个?有解决方法吗?我做错了什么?

【问题讨论】:

  • 这个错误 - openradar.appspot.com/7470644 似乎相关吗?
  • 是的!这是完全相同的错误,但该解决方案非常丑陋。您找到更好的解决方法了吗?
  • 我也遇到了这个错误。非常令人沮丧。
  • 这已作为一个错误提交给 Apple
  • 我今天仍然遇到这个问题。例子,推屏A,然后B,在B的viewDidLoad中做:[self.navigationController setViewControllers:@[B] animated:NO];出于某种原因,如果我在推送屏幕之前隐藏导航栏,然后在 (self.navigationController.navigationBarHidden = NO) 之后取消隐藏,问题就会消失。

标签: iphone uiviewcontroller uinavigationcontroller


【解决方案1】:

我在 Xcode 9.4.1iOS 11.4 中仍然面临这个问题。

最简单的方法是为导航堆栈中的所有先前视图控制器调用loadViewIfNeeded()

let menuViewController = ...
menuViewController.loadViewIfNeeded()

let submenuViewController = ...

navigationController.setViewControllers([menuViewController, submenuViewController], animated: true)

【讨论】:

    【解决方案2】:

    我遇到了同样的问题,Apple 似乎没有更正该错误,因此该线程的选定答案似乎不正确。 我设法使用 this bug report 纠正了这个问题,就像 Anurag 的评论和 Scott Pfeil 的评论一样。

    代码如下:

    navController.navigationBarHidden = YES;
    
    NSArray* viewControllers =  navController.viewControllers;
    UIViewController* currentController = [viewControllers objectAtIndex:viewControllers.count-1];
    
    NSArray *controllers = [NSArray arrayWithObjects: viewController , currentController , nil];
    
    [navController setViewControllers:controllers animated:NO];
    
    navController.navigationBarHidden = NO;
    

    我在 currentController 的 viewDidLoad 中调用此代码,我所做的只是用 viewController 替换以前的控制器。

    希望这会有所帮助。

    【讨论】:

    • 将导航栏设置为隐藏然后显示它为我解决了这个问题。
    • 通过在 setViewControllers() 之前和之后切换导航栏的隐藏状态,我可以缓解同样的问题。就我而言,这只是在应用程序的“冷启动”期间发生的。 (例如,应用程序被用户强行杀死,用户稍后点击了推送通知)。真正连线的是,苹果在其文档中提到了这个确切的用例:“当您想要将导航控制器返回到以前的状态时,这可能在启动时是合适的。” (来源:developer.apple.com/documentation/uikit/uinavigationcontroller/…
    【解决方案3】:

    您还可以将根视图控制器设置为 UINavigationController 的委托,例如:

    @interface YourViewController : UIViewController <UINavigationControllerDelegate> {
    

    然后在 didShowViewController 委托方法中手动设置可用的视图控制器:

    -(void)navigationController:(UINavigationController*)navigationController didShowViewController:(UIViewController*)viewController animated:(BOOL)animated {
        [[viewController navigationController] setViewControllers:[[viewController navigationController] viewControllers]];
    }
    

    让我知道这是否适用于您的环境!

    【讨论】:

      【解决方案4】:
      [self.navigationController setViewControllers:newViewControllers animated:NO];
      

      这可能会对您有所帮助。

      【讨论】:

        【解决方案5】:

        两个同样丑陋的变通方法。

        首先, 如果:

        [self.navigationController popToViewController:someViewController animated:YES];
        

        效果很好,尝试在堆栈上压入一个额外的视图控制器,然后调用:

        [self.navigationController popToViewController:someViewController animated:NO];
        

        意思是你应该在没有任何动画的情况下到达你想要的vc。

        第二,

        设置栈前,设置leftButtonBarItem = nil; 有效地删除旧视图控制器的按钮。事实上,如果标题是错误的,也可以改变它。

        两者都不完全干净,但可能会为您带来想要的结果。

        【讨论】:

          【解决方案6】:

          Apple 似乎已在最新的 SDK 中修复了此问题

          【讨论】:

          • 使用 Xcode 9.0 我也面临同样的问题。这是一个错误吗?
          猜你喜欢
          • 2011-08-11
          • 1970-01-01
          • 1970-01-01
          • 2011-12-21
          • 2013-05-27
          • 2017-09-09
          • 1970-01-01
          • 1970-01-01
          • 2013-10-31
          相关资源
          最近更新 更多