I'm sharing this as it took me A while to figure out. This is if you need to get rid of a double stack of modal views IF it is pressent.
if(self.parentViewController.parentViewController)
[self.parentViewController.parentViewController dismissModalViewControllerAnimated:YES];
else
[self dismissModalViewControllerAnimated:YES];
I have a view that sometimes gets called from a modal view. In that case I would need to get rid of both views at the same time. While dealing with the situation where it was the only modal view. This worked.
As of xCode 4.2 this is no longer working, The new way to deal with this situation is:
if(self.presentingViewController.presentingViewController)
[self.presentingViewController.presentingViewController dismissModalViewControllerAnimated:YES];
else
[self dismissModalViewControllerAnimated:YES];
As pointed out by #Hollance in a relevant thread of mine:
iOS 5 SDK treating UIViews differently
"There is a new property in iOS 5 named presentingViewController. The meaning of parentViewController got changed a bit with the new container view controller API, so it may not always be set when you think it is. That's what presentingViewController is now for."
Related
I am facing a crash on iOS 6.0. I have a view controller from which I present a navigation view controller modally and then from the navigation stack I present another view controller modally and finally to dismiss the whole modal stack I pass the following message to my first view controller from where I showed the navigation controller.
Now this works fine on iOS below 6.0. How should I handle this?
[self dismissModalViewControllerAnimated:YES];
I had this similar crash as well and one of the things helped me solve it was adding:
vc.modalPresentationStyle = UIModalPresentationCurrentContext;
maybe because dismissModalViewController is deprecated in iOS6? Try
[self dismissViewControllerAnimated:YES completion:nil];
EDIT: Lets say you add a method to appDelegate called 'makeMeNumberOne:(UIViewController *)vc':
(I know you use the 'modal' versions, they are deprecated in iOS6, switch to 'presented' variants)
. Also I assume you can find the navigationController, if this is a problem add a comment I'll further expand this, and assume you are using ARC.)
the parameter you have is a strong reference, it holds the current presented viewController, lets call it pvc
ask the navigationController for its viewControllers, and get the last one
as a debugging tool, verify that this vc has a non-nil presentedViewController property
message the last view controller above:
[lastOne dismissViewControllerAnimated:NO completion:^{
[navigationController.viewControllers = #[pvc];
}];
i have a tough one for you today. I have two tableViews in my app the first is on the first page. There are two other pages the user drills down to get to the second table view. After i leave the first table view, i can press the back buttons to get back perfectly until i reach the second table view. As soon as i drill down to the second table view and then try to return to the first via pressing the back buttons. As soon as i get to the last back button to return to the first table view, the app crashes. The code for the back buttons is simply:
- (IBAction)goBack:(id)sender {
[self dismissModalViewControllerAnimated:YES];
}
Any Help Would be greatly appreciated!! Thanks everyone!! :D
Whenever I create a modal view controller from a XIB, the automatic #property generator duplicates things in the Dealloc method, thus throwing an EXC_BAD_ACCESS when the view is dismissed. Make sure you aren't releasing something twice.
Sounds like your are releasing something too early. Open you app in instruments (command + i) and run a zombie test.
As soon as you see zombie has been messaged expand the right panel and have a look at the user code (your code) blocks. Indicated by the back person icon.
Double click that and it will indicate what it was trying to access that had already been released.
Are your tableviews being displayed in a modal window? If not, why are you calling [self dismissModalViewControllerAnimated:YES]? Shouldn't you be calling [[self navigationController] popViewControllerAnimated:YES]?
If you're using a UINavigationController, the back button functionality should be provided automatically.
if you are using [[self navigationController] popViewControllerAnimated:YES] to
then for back you write as mentioned below:
(IBAction)goBack:(id)sender {
// Tell the controller to go back
[self.navigationController popViewControllerAnimated:YES];
}
if you are using [self presentmodalviewcontroller: animated:]
then only [self dismissModalViewControllerAnimated:YES] will work
you try this [[self navigationController] popViewControllerAnimated:YES]
My app is crashing when I am trying to dismiss a modal view using:
[self dismissModalViewControllerAnimated:NO];
This is the flow of the application:
ViewController (My app landing screen) --> Push couple of view controllers --> Show the modal view.
Now, is my intention of canceling the modal view from the same modal controller (self) is correct or should I cancel it from somewhere else.
I had tried passing the object of the last conroller class in the stack to my modal controller and tried following code but it still crashes:
[self.lastStackObj dismissModalViewControllerAnimated:NO];
Appreciate if someone can guide!!!
try this :
[self.parentViewController dismissModalViewControllerAnimated:NO];
maybe you're releasing an already released object in the dealloc.
try commenting all the release statements in the dealloc & then try running, hopefully it wont crash.
You can fix it by finding the variable & releasing it only once.
There maybe other problems causing this too. But this is the first thing i'd look for.
I'm doing the following:
[self.parentViewController dismissModalViewControllerAnimated:YES]
This code fails using the Simulator but works with no issues on the phone itself. The Simulator's console shows no erros. I used NSLog statements to pinpoint this line of code as the culprit. When running on the phone, however, the console(window>organizer) shows that the above code is executed and the application proceeds forward with no problem.
When running the code in debugger, the following statement appears at the bottom of the Xcode debug window:
GDB: Data Formatters temporarily unavailable, will re-try after a 'continue'. (Not safe to call dlopen at this time.)
Then a window dispalys stating: Loading 43672 stack frames. (that sounds bad)
In the debug window the following line appears numerous times:
[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:]
Without getting too deep into my code, does anyone know about or have experience with this type of condition?
Thanks
Why you don't just call [self dismissModalViewControllerAnimated:YES]. It is quite enough to close you modal view controller.
I know, it isn't answer for your question, but maybe it helps to avoid your issue.
I think where you are calling this from is key but you don't say where this code is.
I suspect that dismissing your parentVC is causing this code to get executed again, which tries to dismiss the parent again... basically an infinite loop.
Thanks for the responses.
Aleksejs - I've tried your suggestion with no success. Thanks for making sure I've done the obvious first.
progrmr - I think you are probably correct - when and where I dismiss the modal view is the key and I'll look into how I'm doing this. I may need to re-architect how I'm handling my views.
This is frustrating because the issue does not happen on the iphone itself, only in the Simulator. And, I just confirmed that with the same MacBook Pro the error does not present itself in the Simulator when I'm working from home - the problem only occurs at my office. Strange, eh?
I'll keep digging and report my findings.
Thanks again.
Update - I didn't solve the problem but instead avoided it by re-structuring things. Before, in applicationDidFinishLaunching:, I presented a Login view controller as a modal view. I then need to display a EULA view controller so the user can agree to some legal stuff. I think my problem was that I was presenting the EULA view as a modal from the Login view (which is also modal). The order in which the modals were being presented/dismissed, I think, was the problem (as progrmr had suspected).
How I avoided the issue? I took the time to learn about the delegation pattern. Now, each modal view (Login and EULA) are presented within the app delegate class and I use delegates to callback when certain actions are taken on the modal views.
You shouldn't use self dismissModalViewControllerAnimated if self doesn't actually have a modalViewController. Just create a protocol that delegates the dismiss from the modal view controller back to the parent. when you push the modal view controller, assign the delegate, then when you want to dismiss it call [self.delegate dismissMe] which in turn calls [self dismissModalViewControllerAnimated:...] on the delegate (the parent).
[[Picker presentingViewController] dismissViewControllerAnimated:YES completion:nil];
Instead of
[[Picker parentViewControl] dismissModalViewControllerAnimated:YES];
and
[self presentViewController:picker animated:YES completion:nil];
Instead of
[self presentModalViewController:picker animated:YES];
I m Copying my code here below :-
-(IBAction)referencewindow:(id)sender
{
frmReferences *reference = [[frmReferences alloc]initWithNibName:#"frmReferences" bundle:nil];
[self presentModalViewController:reference animated:YES];
}
There are number of places I m using presentModelViewController and my problem is that stack shows memory leakage due to presentmodelviewcontroller.
when we use presentModelViewController to call other nib as above stated then it just override to the previous view but previous view is still in process thats why memory lekage problem is occuring so please tell me when i call other nib file using presentModelViewController then how to unload that previous view from memory while switch to other view and then on other view to next view.
You must release your viewController after call the presentModalViewController method like here:
- (IBAction)referencewindow:(id)sender {
frmReferences *reference = [[frmReferences alloc]initWithNibName:#"frmReferences" bundle:nil];
[self presentModalViewController:reference animated:YES];
[reference release];
}
There is more information here: Modal View Controllers
Your building a navigation hierarchy using present modal view? It could work but you need to released it sometime.
I think if you tried using normal memory management rules it would work out. Try going back from your views and they should be released, you'd see the memory go down in instruments.