【问题标题】:UIViewControllerHierarchyInconsistency when trying to present a modal view controller尝试呈现模态视图控制器时的 UIViewControllerHierarchyInconsistency
【发布时间】:2012-09-08 05:36:27
【问题描述】:

尝试使用以下代码呈现模态视图控制器

MapViewController *mapView = [[MapViewController alloc] initWithNibName:@"MapViewController" bundle:nil];
    mapView.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
    [self.navigationController presentModalViewController:mapView animated:YES];
    [mapView release];

不断收到以下错误..

'UIViewControllerHierarchyInconsistency', reason: 'A view can only be associated with at most one view controller at a time! View <UIView: 0x1ed815a0; frame = (0 20; 320 460); autoresize = W+H; layer = <CALayer: 0x1ed81600>> is associated with <UIViewController: 0x1ed835a0>. Clear this association before associating this view with <MapViewController: 0x1dd947c0>.'

这是一个我好几个月没碰过的老项目,不知道是什么导致了这样的错误?

【问题讨论】:

    标签: ios objective-c xcode uiviewcontroller xib


    【解决方案1】:

    这在我最新的 Xcode 版本中已经发生过两次。 在这两种情况下,我都需要对 UIViewController 的 XIB 文件进行更改(在您的情况下,它将是 MapViewController.xib:

    之前:

    1. 将主视图移出视图控制器的子级:
    2. 从 XIB 中删除 View Controller(没有必要,因为 File's Owner 应该已经属于它的 Class):

    之后:

    【讨论】:

    • 我希望我能给你更多的支持,这解决了我使用单独的 XIB 文件来表示 UIPopupController 用作其 contentViewController 的自定义 ViewController 的视图的问题。
    • 这个解决方案也解决了我的问题。但是,不要忘记将视图的引用出口设置为其文件的所有者!
    【解决方案2】:

    我在 iOS 6 模拟器上运行 Apple 的示例音频应用程序 MixerHost 时遇到了这个问题。

    上述修复的等价物,即通过将 View 对象拖到顶层来编辑提供的 MixerHostViewController.xib,并丢弃曾经包含它的现在为空的 ViewController,效果很好(虽然不是在我之前花了几个小时找出根本问题是什么,所以我现在感觉苹果已经完成了 - 似乎他们收紧了一些东西,但没有费心检查它是否破坏了他们的示例应用程序)。

    【讨论】:

    • 非常感谢您记录这一点,它帮助我完成了完全相同的事情,而且我非常擅长自己解决这个问题。
    • 您能给我详细介绍一下如何解决这个 MixerHost 问题吗?
    • 对不起@sandy,我想不出更多可以添加到上面的内容了。它只是一个鼠标单击和拖动,一个鼠标选择和一个删除。你试过了吗?你被卡住了吗?
    • @user1681572 我修复了它只需要将 UIview 拖到 viewcontroller 下,工作正常.. 谢谢
    • @sandy 你是对的,第二步,删除空视图控制器,不是绝对必要的,但因为它是示例代码,你可能会稍后再看,这可能是一个好主意通过删除它来清理。否则你可能会浪费时间想知道它为什么会在那里。
    【解决方案3】:

    当我的 Nib 在顶层文件中有 UIViewController 时,我遇到了这个问题。因此,从 Nib 加载创建了 UIViewController,然后我尝试在我的类中使用它,它位于代码中 MapViewController 的位置。

    在我的情况下,解决方案只是从我的 Nib 文件中删除 UIViewController。

    【讨论】:

    • 这听起来像是可能的解决方案。在代码和 .xib 文件中创建视图控制器是一个常见错误。
    【解决方案4】:

    你应该这样做..

    MapViewController *mapView = [[MapViewController alloc] initWithNibName:@"MapViewController" bundle:nil];
    UINavigationController *navCntrlr = [[UINavigationController alloc] initWithRootViewController:mapView];
    mapView.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
    //hide navigation bar if needed
    [self.navigationController presentModalViewController:navCntrlr animated:YES];
    [mapView release];
    

    【讨论】:

    • 这只是将错误更改为...'NSInvalidArgumentException',原因:'应用程序试图以模态方式呈现活动控制器。'
    • 谢谢,但编辑后的答案中的代码将其带回相同的旧错误。'UIViewControllerHierarchyInconsistency',原因:'一个视图一次最多只能与一个视图控制器相关联!查看 > 与 相关联。在将此视图与 .' 关联之前清除此关联
    【解决方案5】:

    也许在某些情况下最好采用另一种方法,并且不要从 NIB 中删除 UIViewController,因为一方面,通过从 NIB 的层次结构中删除视图控制器,您将失去 Auto布局边距。

    为什么不将 UIViewController 留在您的 nib (.xib) 中并在文件所有者类中为它创建一个出口?然后,不是直接在您的代码中实例化视图控制器,而是使用 UINib 类加载 nib,并在最佳时间(从内存/资源使用的角度)调用 nib 实例的 instantiateWithOwner() 方法来取消归档 NIB 并连接nib 对象指向所有者类的出口。

        @IBOutlet var myViewController: myViewController?
    
        var nib : UINib?
        nib = UINib(nibName: "TheNib", bundle: nil)
        if (nib == nil) {
            println("could not load nib: TheNib.xib")
        }
        nib!.instantiateWithOwner(self, options: nil)
    

    【讨论】:

    • 考虑是否要从 nib 文件中初始化 myViewController 的子类。您的解决方案无法获取子类,仍然是 myViewController。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-01
    • 2010-11-27
    相关资源
    最近更新 更多