dismissViewControllerAnimated prevents new UIViewController from showing - ios

I am trying to replace one UIViewController with another, However I have ecountered a problem.
If I write this
[self dismissViewControllerAnimated:NO completion:nil];
//load currentProjectListViewController
currentProjectListViewController = [[CurrentProjectListViewController alloc] initWithNibName:#"CurrentProjectListViewController" bundle:nil];
[self presentViewController:currentProjectListViewController animated:NO completion:nil];
This almost works, however the view just blinks and nothing happens.. no new view is loaded or anything, I have put a break point inside currentProjectListViewController and the thread never makes it there.
however if I do this.
//load currentProjectListViewController
currentProjectListViewController = [[CurrentProjectListViewController alloc] initWithNibName:#"CurrentProjectListViewController" bundle:nil];
[self presentViewController:currentProjectListViewController animated:NO completion:nil];
currentProjectListViewController loads perfectly fine. however I am worried about whats hapening with the previous view? is it stuck there in memory? or is it gone?
my question is how can I dismiss it from memory as well as site without stopping my next view from appearing.
any help would be greatly appreciated.

No, the second way is the correct way as far as I see it. In the first method you're asking the VC to dismiss before a new VC is presented. This would be there is no view, which wouldn't happen.
Bu presenting a new VC, the old VC won't be retained in memory as the nature of the view is that it only uses memory when it is in view. I hope this make makes sense.

Try presenting the new view controller in the completion handler of the dismiss method call:
typeof(self) __weak weakSelf = self; //Need to have a weak reference to self to prevent retain cycle.
[self dismissViewControllerAnimated:NO completion:^{
currentProjectListViewController = [[CurrentProjectListViewController alloc] initWithNibName:#"CurrentProjectListViewController" bundle:nil];
[weakSelf presentViewController:currentProjectListViewController animated:NO completion:nil];
}];

Related

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

Proper way to clean up views after calling presentViewController?

I got an app with a logoff button on all of my pages. When the logoff button gets pressed i want my app to go to my login screen. I do this by calling the following in my IBAction for the logoff button:
loginScreen = [[GP_MobilViewController alloc] initWithNibName:#"GP_MobilViewController" bundle:nil];
[currentView presentViewController:loginScreen animated:YES completion:nil];
Now my problem is i don't know how to remove all of the previous created screens. Because form what i can tell, presentViewController won't remove anything for me, so i have to do this cleanup myself?
PS. I'm not using a UINavigationController. So popToRootViewControllerAnimated:YES, Won't work for me. I need another solution. Thanks in advance.
self.view.window.rootViewController = self;
or in the completion block,
loginScreen = [[GP_MobilViewController alloc] initWithNibName:#"GP_MobilViewController" bundle:nil];
[currentView presentViewController:loginScreen animated:YES completion:^{
[UIApplication sharedApplication].keyWindow.rootViewController =loginScreen;
}];
or in your loginViewControllers-viewDidAppear also you can set it as rootViewController to window.
This makes all the viewControllers to be freed.

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.

dismissViewControllerAnimated results in empty screen

I present modal view which is a navigation controller:
UINavigationController *nvc = [[UINavigationController alloc] initWithRootViewController:photoEditVC];
[self presentViewController:nvc animated:YES completion:NULL];
Once I'm done with the modal view, inside nvc's visible controller:
[self.presentingViewController dismissViewControllerAnimated:YES completion:NULL];
Result
Any ideas why this could happen?
UPDATE:
I realized this only happens when before dismissing the view, I update a value in a shared singleton class, I use to keep track of events.
[[SAStatus current] setValue:#(ua_photoSubmitted) forKeyPath:#"actions.user"];
[self dismissViewControllerAnimated:YES completion:NULL];
But it works fine if I do this:
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[[SAStatus current] setValue:#(ua_photoSubmitted) forKeyPath:#"actions.user"];
}];
or I can do this and it also works fine:
[self dismissViewControllerAnimated:YES completion:^{
[[SAStatus current] setValue:#(ua_photoSubmitted) forKeyPath:#"actions.user"];
}];
At the time, no other classes observer that variable so I do not understand why it would affect the modal view.
Not sure that this is causing the black screen, but the presented view controller should call dismissViewController on itself, not on the presenting view controller.
[self dismissViewControllerAnimated:YES completion:nil];
I saw this issue with iOS 8 GM. Dismissing with animated set to NO did the trick.

View Controller Presentation Warning - Presenting two at the same time

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

Resources