View Controller Presentation Warning - Presenting two at the same time - ios

I am getting this warning when I try to present a second VC modally.
Warning: Attempt to present <RCTAddCardViewController: 0x1f5b21e0> on <IRSlidingSplitViewController: 0x1f538140> while a presentation is in progress!
Here is how I'm doing it:
UIViewController *pvc = [self presentingViewController];
[self dismissViewControllerAnimated:YES completion:^{
RCTAddCardViewController *vc = [[RCTAddCardViewController alloc] initWithNibName:nil bundle:nil];
[pvc presentViewController:vc animated:YES completion:nil];
}];
I shouldn't be getting the error bc it's being presented inside the completion handler of the first VC's dismissal. Anyone know a way to get this to go away?

Since you're calling -dismissViewControllerAnimated: on self, if you were also presenting a view controller by self, that view controller would be dismissed (so pvc would still be presenting self). If that's not the issue, I guess it only counts the presentation complete after the completion block has returned.
One workaround would be to create a -myPresentViewController: method, and use use
[self performSelector:#selector(presentViewController:) withObject:vc afterDelay:0.001]
inside the block

Related

Obj C - Present view controllers one after another

It may be simple, but i'm scratching my head to find out the issue.
I'm presenting a UINavigationController and once it's dismissed I need to present another one which is a UITabBarController, when I do that I get below error
Warning: Attempt to present < MyTabBarViewController: 0xXXXX > on <
ParentViewController: 0XXX> whose view is not in the window hierarchy!
UINavigationController *nav = [self.storyboard instantiateViewControllerWithIdentifier:#"myWeb"];
MyWebViewController *webVC = (MyWebViewController *)nav.topViewController;
[self presentViewController:webVC animated:YES completion:nil];
I can see MyWebViewController is presented without any issue, once the previous one is dismissed, I try to present next one like below, I'm getting the above warning.
MyTabBarViewController *trController = [[MyTabBarViewController alloc] init];
[self presentViewController:trController animated:NO completion:nil];
You need to present MyTabBarViewController only when the MyWebViewController has finished dismissing,
try adding a delay like this:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
MyTabBarViewController *trController = [[MyTabBarViewController alloc] init];
[self presentViewController:trController animated:NO completion:nil];
});
if this works, you will need to get rid of that (in case you want to keep your code clean) and call a delegate method inside completion telling the parent that the MyTabBarViewController is ready to be presented.

Creating modal view from another modal view fails

In a view that was created modally, pressing a button causes the modal view to be dismissed and another modal view to load.
- (void)loadLanguageSelectionView {
[self dismissViewControllerAnimated:YES completion:nil];
UIViewController *languageSelectionController = [[LanguageSelectionViewController alloc] initWithNibName:nil bundle:nil];
[languageSelectionController setModalPresentationStyle:UIModalPresentationCustom];
[languageSelectionController setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
[self presentViewController:languageSelectionController animated:YES completion:nil];
}
The following error is thrown when this code block executes:
DenkoStation[4259:73173] Warning: Attempt to present <LanguageSelectionViewController: 0x7b185430> on <ViewController: 0x79f52e50> whose view is not in the window hierarchy!
What surprises me is the fact that the code was running happily before I made some changes to my code as outlined here.
Where's the mistake?
Because you are trying to present a viewController on top of a viewController which is already dismissed and no longer in window hierarchy.
What you can try is, you can take the ParentViewController reference from current viewController and then you can present new viewController on ParentViewController Like This :
- (void)loadLanguageSelectionView {
UIViewController *parentController = self.presentingViewController;
[self dismissViewControllerAnimated:YES completion:^{
UIViewController *languageSelectionController = [[LanguageSelectionViewController alloc] initWithNibName:nil bundle:nil];
[languageSelectionController setModalPresentationStyle:UIModalPresentationCustom];
[languageSelectionController setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
[parentController presentViewController:languageSelectionController animated:YES completion:nil];
}];
}

Ignoring Warning about detached ViewControllers

I am loading a ViewController from a Storyboard like this:
SSContentViewController* contentViewController =
[[UIStoryboard storyboardWithName:#"Main_iPhone" bundle:nil]
instantiateViewControllerWithIdentifier:#"settingsViewController"];
and add it to my ViewController Array:
[self.viewControllers addObject:contentViewController];
inside the SettingsViewController I have a segue with presents a modal view controller. If I perform this segue I get a "Presenting view controllers on detached view controllers is discouraged"-Warning in the console output.
But there is nothing wrong with it. Everything is working as expected. Is it safe to ignore this warning?
EDIT:
The problem is that the ViewController on which I perform the segue is added to my RootViewController with:
[rootVC.view addSubview:viewController.view];
So I know that it is detached. But even with that warning things are working as they should and do not produce visual errors, etc...
you should actually use presentViewcontroller and dismissviewcontroller to avoid this.
Instead of adding use:
[self.view.window.rootViewController presentViewController:contentViewController animated:YES completion:nil];
And from model view use below to dismiss:
[self dismissViewControllerAnimated:YES completion:nil];
Edit 01:
for frame rate drop try below:
[picker dismissViewControllerAnimated: YES completion:^{
[self performSelector:#selector(reinit) withObject:nil afterDelay:2];
}];

Presentview(full screen) controller while dismissing View1 which is model view itself

I have an ipad app.
I am trying to open view 2 (kind of push view) full with entire screen. how normally do with push view or UIModalPresentationFullScreen. but my base view which is view 1 is also modal view.
so i was trying to open view 2 when view 1 get dismiss…
- (void) handleNewButton :(int)id
{
[self dismissViewControllerAnimated:YES
completion:^{
NewViewController *View2 = [NewViewController alloc] init];
View2.modalPresentationStyle = UIModalPresentationFullScreen;
View2.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentViewController: View2 animated:YES completion:nil];
}];
}
but my view 2 is not opening. i know i can not do push view. But is there any way to achieve it?.
When you do this dismissViewControllerAnimated the UIViewController (self in this case) is gone, in the sense that he is not on the screen anymore, if it has been released or not, that's another story. The reason for you to not be able to show the View2 (very poor name, it should at least ViewController2) is because you are trying to show it from a UIViewController that is not on the screen anymore.
So, what can you do?
The current self in the context of the handleNewButton method, in theory was presented by another UIViewController, that's from where you want to present your View2.
Probably the quickest way of implementing of what I said, would probably be with a notification described here. Although I would do it with a block, so when the self would be created, I would pass a dismissiCompletionBlock that would be called when that UIViewController was dismissed.
try to allocate NewViewController with nib name if you are not using storyboard,
[self dismissViewControllerAnimated:YES
completion:^{
NewViewController *n=[[NewViewController alloc]initWithNibName:#"NewViewController" bundle:nil];
View2.modalPresentationStyle = UIModalPresentationFullScreen;
View2.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentViewController: View2 animated:YES completion:nil];
}];
or if you are using storyboard get NewViewController using identifier.

Dismiss UIViewController after presenting another one

I'm developing a single view iOS 5.0+ app and I'm going to navigate throw my ViewControllers this way:
SearchViewController* search =
[[SearchViewController alloc] initWithNibName:#"SearchViewController"
bundle:nil];
[self presentViewController:search
animated:NO
completion:nil];
My question is, if I'm opening SearchViewController from HomeViewController, is HomeViewController dismissed after SearchViewController is shown?
I have a lot of UIViewControllers and I don't know if all of them will be on memory while user is navigating between them.
If You want to Present Only one Viewcontroller you can try like,
SearchViewController* search =
[[SearchViewController alloc] initWithNibName:#"SearchViewController"
bundle:nil];
[self dismissViewControllerAnimated:NO completion:^{
[self presentViewController:search
animated:NO
completion:nil];
}];
When you present a ViewController from another ViewController, they never get released from memory. To release them from memory you need to explicitly dismiss them.
The method presentViewController:animated:completion: sets the
presentedViewController property to the specified view controller,
resizes that view controller’s view and then adds the view to the view
hierarchy.
So you see you are getting a stack of ViewControllers and adding a View on top of another.

Resources