Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIViewControllerHierarchyInconsistency

Tags:

ios

I am trying to build my app and at one point I push a UIViewController and then I get this error. I am not exactly sure why.

'UIViewControllerHierarchyInconsistency', reason: 'A view can only be associated with at most one view controller at a time! View > is associated with . Clear this association before associating this view with .'

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];

In my pageViewController...................

- (id)initWithManagedObjectContext:(NSManagedObjectContext *)initManagedObjectContext
{
    if ((self = [super initWithNibName:@"PageView" bundle:nil]))
    {
        [self setManagedObjectContext:initManagedObjectContext];
        dataSource = [[PagesDataSource alloc] initWithManagedObjectContext:[self managedObjectContext]];
    }
    return self;
}
like image 405
BDGapps Avatar asked Aug 09 '12 05:08

BDGapps


3 Answers

Gotcha scenario: If you have two UIViewControllers in the same .XIB file with view outlets pointing to the same view, you will raise the UIViewControllerHierarchyInconsistency exception when the nib is loaded, such as by calling the .view property on one of the view controllers.

like image 102
Matt Mc Avatar answered Nov 15 '22 02:11

Matt Mc


Just to add to Matt's and owenfi's answers, in general lines (or at least what I have seen so far) this happens when you create a custom XIB for a UIViewController and in Interface Builder you add both a View Controller and a View where your view object is a subview of your View Controller.

This causes the view's outlet to be set both to the UIViewController you have in IB and to the class set as the file's owner, thus the UIViewControllerHierarchyInconsistency exception.

See this answer for some screenshots explaining the issue.

like image 30
jere Avatar answered Nov 15 '22 02:11

jere


I was having the same issue for popover controls after migrating to iOS 6. However, my implementation was slightly different than the answers here. So, I would like to share my solution:

I have a view in the xib but it is shown in different location with different data on the screen in a popup view. When I show the view, I create a UIViewController and assign my view as the controller's view. It works at the first time but when I try to show it second time, it crashes with UIViewControllerHierarchyInconsistency. So, I defined a global UIViewController once as seen in the code below.

Crashing:

-(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];
}

Fixed:

-(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];
}
like image 3
Topsakal Avatar answered Nov 15 '22 03:11

Topsakal