Why does animating a modal view controller onscreen cause a crash here? - iphone

This piece of code works fine. However, if I change the animated parameter to YES it crashes.
AccountViewController *accViewController = [[AccountViewController alloc] initWithNibName:#"Account" bundle:nil];
[self.navigationController pushViewController:accViewController animated:NO];
[accViewController release];
What could be wrong?

Are you doing this while any other animation is going on? I've seen crashes here in that type of situation (for example, while one view is being dismissed, pushing or presenting another will crash.)

Try dropping the release call. Although I would assume that push should retain, I can't recall for sure and i am not sure when it retains.

Related

Presenting a ModalViewController inside a ModalViewController

I have a view which is presented as a modal view controller which takes username and password credentials. I want this view to check the delegate, and if the user hasn't previously set an unlock pin for the app, to then show the change pin view as a modal view controller. This is my code...
+(void)presentCredentialsViewController:(UIViewController *)vc{
CredentialsViewController *cvc = [[CredentialsViewController alloc] init];
[vc presentModalViewController:cvc animated:FALSE];
}
and then in CredentialsViewController
-(void)viewDidLoad{
[super viewDidLoad];
if([appDelegate.pin isEqualToString: #""]){
UserPrefsViewController *upvc = [[UserPrefsViewController alloc] init];
upvc.cancelButton.hidden = true;
[self presentModalViewController:upvc animated:FALSE];
}
}
But for some reason it doesn't work. The debugger steps through the code without error, never the less, the second modal view controller isn't displayed.
First, I would suggest checking that your appDelegate.pin is blank and not nil. If it is nil, the if statement would not be satisfied and your second ModalView would not be presented.
You may also want to try the previous suggestion, calling presentModalViewController from viewDidAppear, or setting a delay if leaving it in viewDidLoad. It is possible that the CredentialsViewController is trying to present the second view when it has not yet presented itself.
The if statement is being hit and the second PresentModalViewController is executing without error, but it just wasn't displaying. I did try putting the code in ViewDidAppear and a load of other places as well, such as applicationWillBecomeActive etc. Although not actually crashing the code, still none of these approaches would show the view controller. In the end I have opted for this:
start with pin of #""
on applicationDidEnterBackground check if pin has been set
if yes
PresentModalViewController: PinViewController
if no
do nothing
Bit of a hack but it will do for now. I suppose I should put some sort of notification in somewhere warning that the pin hasn't been set. The suggestion about the delay may possibly work I suppose. I might give it a go in the future. Thanks guys....points up!

Memory leak on popToViewController

Hi
I am using following method to go back to one of the previous view. This is working. But I got two issues with this.
This line gives a memory leak when I use Instrument.
After popup to particular view, when I press left navigation button (back button) just only this button will disappear and view will remain.
Can anyone please let me know how to overcome these issues?
[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:1] animated:YES];
Thank you
try [self.navigationController popViewControllerAnimated:YES]; if you just with to remove current view from the view hierarchy,
If you, as you describe, just wants to pop just the active viewController, you can use
- (UIViewController *)popViewControllerAnimated:(BOOL)animated
documentation here.
If this still give problems, there is something wrong with your viewController hierarchy.
Hi agree with the above answers
try these methods carefully
[self.navigationController popToRootViewControllerAnimated:YES];
[self.navigationController popToViewController:(UIViewController*)
animated:(BOOL)];
Working with iOS5.
[self.navigationController popViewControllerAnimated:(BOOL)];

Back and forth, removeFromSuperView

Im a bit confused...
I have a mainview, which by the click of a button shows a subview. What I want to do next is to
be able to switch back and forth between the Main and the Sub, but when I do this, the return button FROM the subView makes the TO SubView button disabled...I cant seem to be able to access the Subview a second time. Nothing happens.
What I have is a UIButton, and an IBAction, which I have written the "[self.view removeFromSuperView];" in.
Please do not get me wrong here, I do get back to the mainView. The problem is that I cant go back to the subview afterwards.
I've read something in the documentation about retaining the subView...But I did not quite understand how to do it.
Could anyone please shed some light over this?
Thanks!
this is just a guess, since you don't provide much code:
- you might first need to retain the view. in case it's only retained by its current superview
[self.view retain];
remember to free it manually when it's no longer needed.
[self.view release];
Why dont you try out this?
to open ur subview:
Ursubview *Ursubview =[[Ursubview alloc] initWithNibName:nil bundle:nil];
Ursubview.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentModalViewController:Ursubview animated:YES];
to go back:
[self dismissModalViewControllerAnimated:YES];
Why not just hide it instead of removing it?

Close one modal ViewController and open another in same method. Possible?

I have a situation where I want to open one modal controller from the other. But when the user closes either, they should go back to the parent controller of both modal controllers.
So I have the parent controller in charge of this. The method on the parent does something similar to the code below when the user clicks a button on the first modal controller.
[self.navigationController dismissModalViewController:YES];
SecondModalViewController *c = [[SecondModalViewController alloc] init];
[self.navigationController presentModalViewController:c animated:YES];
[c release];
The only thing that happens is the first view closes, but I don't see the second view open. Is it possible to close a modal ViewController and open a second one in the same method? If so, how?
i think that by the time you close the first view controller, the [self.navigation presentmodal..] dosen't have a self to open the new one from.
you could do that:
use a boolean variable to state whether the next time this controller appears (when you close the one you're currently trying to open), it should close, and implements that feature in the viewDidApper: method, like so:
#interface FirstViewController : UIViewController
{
//...
BOOL close;
}
and in the .m file,
-(void)viewDidAppear:(BOOL)animated{
if(close)
[self dismissModalViewControllerAnimated:NO];
else
[super viewDidAppear:animated];
}
now, to open your new controller, do that:
-(IBAction)openSecondController:(id)sender{
//..
SecondViewController* controller = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
close = YES;
[self presentModalViewController:controller animated:NO];
}
now, when you close the second one, the first one will close also. doesn't have any visible side affects in my apps..
not the cleanest way, but i didn't find a better one.
cheers
I do that same thing all the time without a problem, though mine have animated:NO... I'm guessing your issue is because you have animated:YES on both. What effect are you looking for exactly? Do you want to see one get animated away, and then the other get animated in? If so, you need to execute the presentModalViewController with a delay.
Otherwise, you should just be able to present the second modal view controller without closing the first one at all. When you call dismissModalViewController; it should dismiss both.
I'm finding exactly the same response. It looks like standard behaviour.
The way I got around it is to use performSelector:withObject:afterDelay:
[self performSelector:#selector(presentController:) withObject:navController afterDelay:0.5f];
The only drawback was I had to set a presentController function which then did the presentModalViewController:animated:
I tried to use a NSInvocation but I kept on getting a bad access error when I tried to pass a BOOL for the animated argument.
The main thing is it works and my client is happy.
You can use handle uiviewcontroller closed and open another with using Unwind Segues.
https://developer.apple.com/library/content/technotes/tn2298/_index.html

popToRootViewController crashing

I am a relatively new iPhone app developer so my knowledge is a little sketchy, so please forgive me if this is a bit of a trivial question.
I have a navigation app which drills between table views by calling pushViewController on the navigationController object
I have one particular section which pushes new view controllers sequentially as the user goes through the interface. The view controllers are all subclassed from UIViewController.
It all works fine until it gets to the end, where the idea is the user presses a "Finish" button and is returned to the root view controller (main menu).
So on the button press I call:
[[self navigationController] popToRootViewControllerAnimated:YES];
And it crashes.
I am a bit worried this could be a big problem as this definitly worked at some point but it is now always failing.
Can anyone give any ideas/advice?
Some suggestions:
Before calling popToRootViewControllerAnimated: confirm that the RootViewController does actually exist. If it died somewhere along the line, calling the method will cause a crash.
Check the – viewWillDisappear: and – viewDidDisappear: methods of your last view to make sure you're not doing something dangerous there.
Not sure if popping a view causes it to always deallocate but check the dealloc method of the views and their controllers to make sure your not over-releasing something.
One mistake I've seen a lot is releasing objects in the data model from controllers. When another controller (in this case the RootViewController) tries to access the data model the app crashes.
It sound's like you need how to use the Xcode debugger. Type in debugger in Xcode help to get pointers.
You should not be using popToRootViewController in your viewWillDisappear.
Instead if you want to pop to root controller on your pressing the back button, you should replace the back button by your own and add an action to it. Try doing something like ::
UIBarButtonItem *back = [[UIBarButtonItem alloc] initWithTitle:#"back"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(goBack:)];
self.navigationItem.leftBarButtonItem = back;
and then handle the action as ::
- (void) goBack:(id)sender
{
// pop to root view controller
[self.navigationController popToRootViewControllerAnimated:YES];
}
As the others have commented, the first step is to run this is debug mode and figure out where and why you are crashing.
The most common type of crash is using a deallocated object (EXEC_BAD_ACCESS). Have you run the static analyzer? Are you properly retaining your object references?