1

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)

vendettacore
  • 1,439
  • 1
  • 13
  • 28
  • What does `showShareWindow` do? and `closeWhiteView` actually close the testWindow? – gabbler Feb 12 '15 at 12:12
  • @gabbler `showShareWindow` does `[testWindow makeKeyAndVisible]` and `closeWhiteView` close `UIWindow` which contain button what calls `-(void)shareWithLinkedIn:(AVMSocNetButton*)sender` method. See my edit for explanation – vendettacore Feb 12 '15 at 12:21
  • How did you do to closeWhiteView and close the window? – gabbler Feb 12 '15 at 12:32
  • @gabbler `-(void)closeWhiteView{ [socialWindow resignKeyWindow]; socialWindow.hidden = YES; socialWindow = nil; }` it works perfect. – vendettacore Feb 12 '15 at 12:36
  • I think `testWindow.hidden = YES;` and it will all work as expected, this is because the testWindow is in the front and block the touch event of buttons, but the textView has already become first responder so it is editable. – gabbler Feb 12 '15 at 13:00
  • So my suggestion is remove testWindow completely, as you see in the source code, `composeViewController` is added as child view controller of the app's root view controller. And it is also the root view controller of the testWindow, the error indicate you can't add a root(composeViewController) as a child of another controller(navigation controller) from another window. – gabbler Feb 12 '15 at 13:08

2 Answers2

1

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)

Alex Chugunov
  • 728
  • 5
  • 10
0

All you want to do is to present your VC on top of root view controller:

- (void)shareWithLinkedIn:(AVMSocNetButton*)sender{
   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"];

   [[[[UIApplication sharedApplication] keyWindow] rootViewController] presentViewController:composeViewController animated:YES completion:nil];
}
orkenstein
  • 2,810
  • 3
  • 24
  • 45
  • it doesn't work. it makes screen black, though `NSLog` shows message that composeViewController exists: `composeViewController ` – vendettacore Feb 12 '15 at 12:45
  • @vendettacore, what `REComposeViewController` does? – orkenstein Feb 12 '15 at 12:53
  • https://github.com/romaonthego/REComposeViewController here is full explanation. So I tried to do the following: `[[[[UIApplication sharedApplication] keyWindow] rootViewController] addChildViewController:composeViewController]; [[[[UIApplication sharedApplication] keyWindow] rootViewController] presentViewController:composeViewController animated:YES completion:nil];` and it shows me what I want, but it kills previous UIViewController – vendettacore Feb 12 '15 at 12:55
  • @vendettacore, why not to use `SLComposeServiceViewController`? – orkenstein Feb 12 '15 at 13:05
  • @vendettacore, try `[composeViewController presentFromRootViewController];` instead of `[[[[UIApplication sharedApplication] keyWindow] rootViewController] presentViewController:composeViewController animated:YES completion:nil];` – orkenstein Feb 12 '15 at 13:05
  • because `SLComposeServiceViewController` is only available for iOS 8.0+ and `[composeViewController presentFromRootViewController]` doesn't work properly – vendettacore Feb 12 '15 at 13:08