18

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;
}
BDGapps
  • 3,318
  • 10
  • 56
  • 75

6 Answers6

12

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.

Matt Mc
  • 8,882
  • 6
  • 53
  • 89
  • 3
    dude, i love you. thanks to your answer i realized what my problem was. i had a `UITableViewController` with a `UITableView` as a subview, but the XIB's file's owner class was a `UITableViewController` subclass, so i removed the `UITableViewController` from the XIB and just left the `UITableView` – jere Oct 03 '12 at 14:21
  • @jere glad to help :) I figured I should post something after spending 1/2 an hour trying to figure it out, with no helpful output from the debugger... – Matt Mc Oct 03 '12 at 20:08
  • I had a MainWindow.xib with a TabBarController, with 4 embedded NavigationControllers with TableViewControllers that would load from separate NIBs that have a TableViewController with a TableView. Removing the TableViewController from the separate XIBs, leaving the TableView and having the File's Owner point to the custom class solved it for me. – bbaassssiiee Oct 23 '12 at 18:53
  • I have same issue http://stackoverflow.com/questions/12909275 . . my project don't have any viewcontroller in XIB, everything in code – Amit Battan Oct 25 '12 at 12:09
4

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.

Community
  • 1
  • 1
jere
  • 4,306
  • 2
  • 27
  • 38
3

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];
}
Topsakal
  • 447
  • 5
  • 11
2

This error will also occur if you don't follow these guidelines: Creating Custom Content View Controllers

Basically, you need to call:

[yourVC removeFromParentViewController];

if you've

[parentVC addChildViewController:yourVC];

This error may often be paired with something about "active view controller"

whyoz
  • 5,168
  • 47
  • 53
1

I had the same error arise when I wanted a settings scroll view to appear in a popover.

Here is my original code with comments about what I changed to resolve it:

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

The line popoverContent.view = settingsViewController.view is what was causing the crash (without it my popover was empty of course). From the point of view of the UIViewControllerHierarchyInconsistency error it makes sense that I shouldn't have been reassigning it and then adding it to another view controller.

In your case I'd guess something similar is happening in pushViewController or elsewhere in your code. Could that be the case at all?

tilo
  • 14,009
  • 6
  • 68
  • 85
owenfi
  • 2,471
  • 1
  • 24
  • 37
  • 4
    Worth mentioning that this started happening for me only as of DP4. – owenfi Aug 12 '12 at 00:05
  • Thank You I did something like this. – BDGapps Aug 12 '12 at 03:40
  • Upvote for owenfi. Crash occurs in DP4 but also in 6b4. I noticed a crash in an app that wasn't there when I originally built it in DP3, b3. So compiling with DP3 was fine. Running my dp3 compiled code in beta4 is crashing. – Daddy Aug 17 '12 at 14:06
  • I have the same problem as @owenfi. I am not sure that the answer really describes what to do. There must be a more general solution and explanation for this. Any suggestions? – Johan Karlsson Sep 04 '12 at 07:44
  • My step by step debugging approach was to comment out the lines where I assigned the view controller and passed the view around and then rebuild in a better way (shown above). I agree thats not a very generally applicable explanation. I didn't see an exact parallel in the original code, so maybe the fix was in lines not shown, perhaps you could post yours in another question if it is substantially different? – owenfi Sep 05 '12 at 09:06
  • I am having an issue like this but I am not assigning 2 view to each other, can someone please help – virindh Sep 15 '12 at 15:08
  • Developer Preview the iOS (or Mac?) betas of iOS 6 Xcode. – owenfi Sep 25 '12 at 05:11
  • I have same issue http://stackoverflow.com/questions/12909275 . . my project don't have any viewcontroller in XIB, everything in code – Amit Battan Oct 25 '12 at 12:10
0

One of the reason I stuck on was that I copied the ViewController from a storyboard to a xib file to be loaded programmatically for my need. But in a xib I should really copy the view not the entire view controller. And set the file owner to my custom view controller. That solves my similar error problem.

karim
  • 15,408
  • 7
  • 58
  • 96