Search code examples
iosobjective-cuitableviewuinavigationcontrollerslcomposeviewcontroller

UIViewControllerHierarchyInconsistency when presenting view controller


I have such View Controller's structure as: UINavigationController(root view controller)->UIViewController. In my UIViewController I have UITableView with dynamic cells. In every cell there is "share" button which presents fullscreen UIWindow. This UIWindow contatins an UIView with social network buttons and each button must show share dialog and everything is ok only for buttons which are work with social network frameworks or libraries but I've a button which must present custom share dialog. And when I press on it my app crashing with following error: *** Terminating app due to uncaught exception 'UIViewControllerHierarchyInconsistency', reason: 'adding a root view controller <REComposeViewController: 0x7f9e8b416260> as a child of view controller:<AVMNavCon: 0x7f9e887540f0>'

That's how I try to show my dialog:

-(void)shareWithLinkedIn:(AVMSocNetButton*)sender{
[self closeWhiteView]; // close UIWindow with social network buttons
REComposeViewController *composeViewController =  [[REComposeViewController alloc] init]; // define and initialize custom share dialog
composeViewController.title = @"Social";
composeViewController.hasAttachment = YES;
composeViewController.attachmentImage = sender.shareImage;
composeViewController.text = [NSString stringWithFormat:@"Share text"];
testWindow = [[UIWindow alloc] initWithFrame:CGRectMake(0, 74, SCREEN_WIDTH-10, SCREEN_HEIGHT/2)];
testWindow.windowLevel = UIWindowLevelStatusBar;
testWindow.hidden = NO;

testWindow.rootViewController = composeViewController;
[composeViewController presentFromRootViewController];

[self performSelector:@selector(showShareWindow) withObject:nil afterDelay:1];
}

As everyone can see here I use another one UIWindow (testWindow). This because if I'll show my dialog without UIWindow my UIViewController will fade away and I'll see share dialog on black background. Then if I comment the line testWindow.rootViewController = composeViewController; I'll see my share dialog as I want but without any interaction (I can't touch buttons everywhere on the screen) How should I present my dialog and avoid this error?

EDIT:

Full hierarchy is: UINavigationController->UIViewController->UITableView->UITableViewCell->UIButton->(calls "WhiteView" UIWindow)->UIWindow->UIButton->(calls shareWithLinkedIn method)


Solution

  • You shouldn't try to use root view controller of a window as a modal. If you want to implement this transition using a window, then use an empty UIViewController with a clear background as the rootViewController and then present your composeViewController as a modal.

    You could accomplish what you're trying to do without using windows. For example on iOS 8, use UIModalPresentationOverFullScreen as modalPresentationStyle for your composeViewController and simply present it as a modal for your current controller. Again, you'd need a transparent container view to do that, but it's cleaner than introducing another window. On iOS 7 you'd need to use UIModalPresentationCustom (seems to be giving the same effect as UIModalPresentationOverFullScreen by default)