UIViewControllerHierarchyInconsistency

时间:2012-08-09 05:26:11

标签: ios

我正在尝试构建我的应用程序,有一次我推了一个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;
}

6 个答案:

答案 0 :(得分:12)

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

答案 1 :(得分:4)

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

这会导致视图的出口既设置为IB中的UIViewController,又设置为设置为文件所有者的类,因此UIViewControllerHierarchyInconsistency例外。

有关解释此问题的截图,请参阅this answer

答案 2 :(得分:3)

迁移到iOS 6后,我遇到了与popover控件相同的问题。但是,我的实现与此处的答案略有不同。所以,我想分享我的解决方案:

我在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];
}

答案 3 :(得分: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是导致崩溃的原因(没有它我的popover当然是空的)。从UIViewControllerHierarchyInconsistency错误的角度来看,我不应该重新分配它然后将它添加到另一个视图控制器。

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

答案 4 :(得分:1)

如果您不遵循以下准则,也会出现此错误:Creating Custom Content View Controllers

基本上,您需要致电:

  

[yourVC removeFromParentViewController];

如果你

  

[parentVC addChildViewController:yourVC];

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

配合使用

答案 5 :(得分:0)

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