17

我正在尝试构建我的应用程序,并且有一次我推送了一个 UIViewController,然后我收到了这个错误。我不确定为什么。

'UIViewControllerHierarchyInconsistency',原因:'一个视图一次最多只能关联一个视图控制器!视图 > 与 关联。在将此视图与关联之前清除此关联。

PageViewController *viewController;

viewController = [[PageViewController alloc] initWithManagedObjectContext:managedObjectContext];
dataSource = [[PagesDataSource alloc] initWithManagedObjectContext:managedObjectContext];

PVPage *selectedPage = [[dataSource pages] objectAtIndex:itemIndex];
[viewController setRepresentedPage:selectedPage];

PageFlipperAppDelegate *appDelegate = (PageFlipperAppDelegate *)[[UIApplication sharedApplication] delegate];
[(UINavigationController *)[[appDelegate window] rootViewController] setToolbarHidden:YES animated:YES];
[(UINavigationController *)[[appDelegate window] rootViewController] pushViewController:viewController animated:YES];

在我的 pageViewController 中......

- (id)initWithManagedObjectContext:(NSManagedObjectContext *)initManagedObjectContext
{
    if ((self = [super initWithNibName:@"PageView" bundle:nil]))
    {
        [self setManagedObjectContext:initManagedObjectContext];
        dataSource = [[PagesDataSource alloc] initWithManagedObjectContext:[self managedObjectContext]];
    }
    return self;
}
4

6 回答 6

12

问题场景:如果在同一个 .XIB 文件中有两个 UIViewControllers 且视图出口指向同一个视图,则在加载 nib 时会引发 UIViewControllerHierarchyInconsistency 异常,例如通过调用其中一个视图控制器的 .view 属性。

于 2012-09-21T01:18:52.197 回答
4

只是为了添加到 Matt 和 owenfi 的答案中,一般来说(或者至少是我到目前为止所看到的),当您为 a 创建自定义 XIBUIViewController并在 Interface Builder 中添加视图控制器和视图时,会发生这种情况。是您的视图控制器的子视图。

这会导致视图的出口设置为UIViewController您在 IB 中拥有的以及设置为文件所有者的类,因此是UIViewControllerHierarchyInconsistency例外。

有关解释该问题的一些屏幕截图,请参阅此答案

于 2012-10-03T14:29:50.133 回答
3

迁移到 iOS 6 后,我遇到了同样的弹出框控件问题。但是,我的实现与这里的答案略有不同。所以,我想分享我的解决方案:

我在 xib 中有一个视图,但它显示在不同的位置,在弹出视图中的屏幕上有不同的数据。当我显示视图时,我创建了一个 UIViewController 并将我的视图分配为控制器的视图。它第一次工作,但是当我第二次尝试显示它时,它会因 UIViewControllerHierarchyInconsistency 而崩溃。因此,我定义了一个全局 UIViewController,如下面的代码所示。

崩溃:

-(void) showInTrainWindow:(int)trainLegId onView:(UIView *)view
{
    //update labels on vwTrain for trainLegId
    [self prepareInTrainProperties:trainLegId];
    UIViewController* popoverContent = [[UIViewController alloc] init];
    popoverContent.view = vwInTrain; //IT WAS CRASHING ON THIS LINE    
    popoverContent.contentSizeForViewInPopover = CGSizeMake(vwInTrain.frame.size.width, vwInTrain.frame.size.height);
    self.popoverController = [[UIPopoverController alloc] initWithContentViewController:popoverContent];
    self.popoverController.delegate = self;    
    [self.popoverController presentPopoverFromRect:CGRectMake(325, view.frame.origin.y - scrollViewTimeLine.contentOffset.y + 65, 1, 1)
                                            inView:vwTimeLine
                          permittedArrowDirections:UIPopoverArrowDirectionLeft
                                          animated:YES];
    [popoverContent release];
}

固定的:

-(void) showInTrainWindow:(int)trainLegId onView:(UIView *)view
{
    //update labels on vwTrain for trainLegId
    [self prepareInTrainProperties:trainLegId];
    if ( self.popoverContentInTrain == nil )
    {
        self.popoverContentInTrain = [[UIViewController alloc] init];
        self.popoverContentInTrain.view = vwInTrain;
        self.popoverContentInTrain.contentSizeForViewInPopover = CGSizeMake(vwInTrain.frame.size.width, vwInTrain.frame.size.height);
    }
    self.popoverController = [[UIPopoverController alloc] initWithContentViewController:self.popoverContentInTrain];
    self.popoverController.delegate = self;    
    [self.popoverController presentPopoverFromRect:CGRectMake(325, view.frame.origin.y - scrollViewTimeLine.contentOffset.y + 65, 1, 1)
                                            inView:vwTimeLine
                          permittedArrowDirections:UIPopoverArrowDirectionLeft
                                          animated:YES];
}
于 2012-10-18T14:27:43.643 回答
2

如果您不遵循以下准则,也会发生此错误:创建自定义内容视图控制器

基本上,您需要调用:

[yourVC removeFromParentViewController];

如果你有

[parentVC addChildViewController:yourVC];

此错误通常与“活动视图控制器”有关

于 2013-03-14T23:30:41.473 回答
1

当我希望设置滚动视图出现在弹出窗口中时,我遇到了同样的错误。

这是我的原始代码,其中包含关于我为解决它所做的更改的注释:

SettingsViewController *settingsViewController;
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Storyboard" bundle:nil];    
settingsViewController = [storyboard instantiateViewControllerWithIdentifier:@"Settings"];

CGRect contentRect = CGRectMake(10, 10, 320, 700);

// This entire object got deleted in the fixed version
UIViewController *popoverContent = [[UIViewController alloc] init];
popoverContent.view = settingsViewController.view;
popoverContent.contentSizeForViewInPopover = contentRect.size;

// Instead of popoverContent I just put the settingsViewController in directly.
UIPopoverController *popoverController = [[UIPopoverController alloc] initWithContentViewController:popoverContent];

[popoverController presentPopoverFromRect:[sender frame]
                                   inView:(UIButton*)sender
                 permittedArrowDirections:UIPopoverArrowDirectionLeft
                                 animated:YES];

该行popoverContent.view = settingsViewController.view是导致崩溃的原因(没有它,我的弹出框当然是空的)。从 UIViewControllerHierarchyInconsistency 错误的角度来看,我不应该重新分配它然后将其添加到另一个视图控制器是有道理的。

在您的情况下,我猜在 pushViewController 或您的代码中的其他地方发生了类似的事情。可能是这样吗?

于 2012-08-12T00:04:52.600 回答
0

我坚持的原因之一是我将 a 复制ViewControllerstoryboard了一个xib文件,以便根据我的需要以编程方式加载。但是在 xib 中,我应该真正复制视图而不是整个视图控制器。并将其设置file owner为我的自定义视图控制器。这解决了我类似的错误问题。

于 2017-06-06T10:29:44.570 回答