64位iOS设备中的UIViewControllerHierarchyInconsistency

时间:2014-03-30 12:32:59

标签: ios objective-c ipad

我正在开发一个iPad应用程序,它有一个视图控制器(称为ContentViewController),其中包含3个不同的视图。

  1. 滑块视图 - 从底部打开,其中包含图标列表。基于选择图标,我必须在内容视图中加载视图控制器
  2. 控制视图 - 屏幕左侧有少量按钮和文字
  3. 容器视图 - 这涵盖了屏幕的大部分内容,我想根据从滑块中选择的图标来加载视图控制器
  4. 这就是我实施它的方式

    在应用程序启动时(第一次),我通常在Container View中加载主视图控制器,它具有包含应用程序相关项的表视图。每个视图控制器都在导航控制器内,我在容器视图中加载该导航控制器

    当我在滑块视图中选择一个图标时,我正在加载一个视图控制器。

    以下是我在名为ContentViewController的视图控制器中实现此代码的代码:

    - (void) itemSelected: (UIViewController *) viewController
    {
       // I am storing view controller in a instance variable currentViewController. The currentViewController is declared as @property (nonatomic , strong) UIViewController *currentViewController under @interface in header file
       if(_currentViewController == nil)
       {
          // This part of code gets executed for the first time, when there is no view controller available in ContainerView
          _currentViewController = viewController;
          [self addChildViewController:_currentViewController];
          [self.containerView addSubview:_currentViewController.view];
       }
       else if(_currentViewController != viewController)
       {
           // If a view controller is already opened in Container View and when I click a icon from the slider, this par of code is getting executed
           [self addChildViewController:viewController];
           [self transitionFromViewController:_currentViewController
                          toViewController:viewController
                                  duration:0
                                   options:UIViewAnimationOptionTransitionNone
                                animations:^{}
                                completion:^(BOOL finished){
                                    [_currentViewController removeFromParentViewController];
                                    _currentViewController = viewController;
                                    [_currentViewController   didMoveToParentViewController:self];
                                }
         ];        
        }
    }
    

    上面提到的代码在iPad2和iPad3上工作正常,它们是32位设备。但是当我在iPad Air(64位设备)上运行此应用程序时,它会在transitionFromViewController中崩溃,引发以下错误:

    Terminating app due to uncaught exception 'UIViewControllerHierarchyInconsistency', reason: 'child view controller:<UINavigationController: 0x136d76130> should have parent view controller:(null) but actual parent is:<ContentViewController: 0x136d39680>'
    *** First throw call stack:
    (0x183642950 0x19001c1fc 0x183642890 0x186688f00 0x18661484c 0x186613ff4 0x10009a224 0x1001104c8 0x18673d798 0x1867fe234 0x186692470 0x1865fe4a4 0x1836030a8 0x183600330 0x1836006bc 0x1835416d0 0x1891ddc0c 0x186672fdc 0x100058028 0x19060faa0)
    libc++abi.dylib: terminating with uncaught exception of type NSException
    

    我尝试了各种选项,例如删除transitionFromViewController并替换为以下代码:

        [_currentViewController willMoveToParentViewController:nil];
        [_currentViewController removeFromParentViewController];
        _currentViewController = firstView;
        [_currentViewController didMoveToParentViewController:self];
    
        [self addChildViewController:_currentViewController];
        [self.containerView addSubview:_currentViewController.view];
    

    但它在最后一行[self.containerView addSubview ....]中再次崩溃,并在iPad Air中提到了同样的错误。我不知道如何继续,我不知道为什么这个问题只发生在64位设备上。有人可以帮我这个。

    提前致谢!

    维涅什

1 个答案:

答案 0 :(得分:3)

我可以通过更改代码来解决此问题。在上面的代码中,我将视图控制器添加为子视图控制器,并从父视图中删除了以前的视图控制器。该代码在非64位设备中运行良好,但在64位设备上运行不正常。所以我只是将视图控制器的视图添加到容器视图的子视图中,并从超级视图中删除了以前的视图控制器。以下是修改后的代码供参考:

if(_currentViewController == nil)
{
    _currentViewController = viewController;
    [self.containerView addSubview:viewController.view];
}
else if(_currentViewController != viewController)
{
    [_currentViewController.view removeFromSuperview];
    [self.containerView addSubview:viewController.view];
    _currentViewController = viewController;
}

它适用于所有设备。