UINavigationController popViewControllerAnimated issue - iphone

I have LoginViewControllerIphone instance , where I push the instance of TasksRootViewControllerIphone
then in TasksRootViewControllerIphone (10 seconds after appearing) I call [self.navigationController popViewControllerAnimated:YES];
And receive an error:
[NSRecursiveLock isSystemItem]: unrecognized selector sent to instance 0x3ba360
I tried to print navigation controller stack:
po [self.navigationController viewControllers]
$2 = 0x003445f0 <__NSArrayI 0x3445f0>(
<LoginViewControllerIphone: 0x3b73c0>,
<TasksRootViewControllerIphone: 0x3af290>
)
So it has proper view controllers. Any ideas how can it happen?
update:
pushing code:
self.tasksRootViewControllerIphone = [[TasksRootViewControllerIphone alloc] initWithNibName:#"TasksRootViewControllerIphone" bundle:nil];
self.tasksRootViewControllerIphone.view.backgroundColor = [UIColor clearColor];
[self.loginViewControllerIphone.navigationController pushViewController:self.tasksRootViewControllerIphone animated:YES];
in TasksRootViewControllerIphone.m I have:
- (void)viewDidLoad
{
[self performSelector:#selector(popCurrentViewControllerAnimated) withObject:self afterDelay:10];
}
- (void)popCurrentViewControllerAnimated
{
[self.navigationController popViewControllerAnimated:YES];
}

Update your viewDidload Method as
- (void)viewDidLoad
{
[self performSelector:#selector(popCurrentViewControllerAnimated) withObject:nil afterDelay:10];
}
hopefully it solve your problem.
As the method popCurrentViewControllerAnimated not take any argument. so withObject should be nil. not self.

I found the point.
The problem was because it's not arc project, and one of the UIBarButtonItems was released one time more.
Strange, but it caused the problem with popViewController.

Related

error when i am calling next view controller

i am getting an error when i am calling next view controller, i want to call a view controller that a action continue .this screen will come appear first time only when we run first time.
controller is not going next view.
-(void)viewDidLoad
{
welcomePage *temp = [[welcomePage alloc]initWithNibName:#"welcomePage" bundle:nil];
[self presentViewController:temp animated:YES completion:^(void){}];
}
Warning: Attempt to present on whose view is not in the window hierarchy!
Try this one..
You change the code in Appdelegate.m didFinishLaunchingWithOptions method like this
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
UINavigationController *nav=[[UINavigationController alloc]initWithRootViewController:self.viewController];
self.window.rootViewController = nav;
And in your ViewDidLoad method like this..
welcomePage *temp = [[welcomePage alloc]initWithNibName:#"welcomePage" bundle:nil];
[self.navigationController presentViewController:temp animated:YES completion:nil];
For dismissing viewcontroller you can write following code in welcomepage button action
-(IBAction)dismiss:(id)sender{
[self dismissViewControllerAnimated:YES completion:nil];
}
use this code
-(void)viewDidLoad
{
welcomePage *temp = [[welcomePage alloc]initWithNibName:#"welcomePage" bundle:nil];
[self presentViewController:temp animated:YES completion:nil];
}
That error means you are trying to present a modal view controller from a view controller that is not currently in the screen.
If You are using Storyboard : Use this
instantiateViewControllerWithIdentifier
UIViewController objController = [self.storyboard instantiateViewControllerWithIdentifier:#"StoryBoard Id"];
[self presentViewController:objController animated:YES completion:nil];
To Set Storybaord ID , Check Here .
This error means that you are trying to present 'welcome page' from a view that is not on the screen yet.
Knowing that simply moving the code to the viewDidAppear method doesn't work for you, what you can try to do is this:
-(void)viewDidAppear
{
[self presentWelcome];
}
- presentWelcome {
welcomePage *temp = [[welcomePage alloc]initWithNibName:#"welcomePage" bundle:nil];
[self presentViewController:temp animated:YES completion:^(void){}];
}
What happens here is that when the view appears (so when it is in the view hierarchy), the controller starts a function that calls the other viewController. hope this solves your problem.
Hope this helps you!

ios: Navigation to another screen using modalTransitionsytle attribute, crashes the app

I have Navigation interface which I use to pop to setting screen everytime uses presses settings button.
#interface Navigation : UINavigationController
{
}
-(void)popToMainMenuAnimated:(BOOL)animated;
//.m file
-(void)popToMainMenuAnimated:(BOOL)animated
{
UIViewController *element;
for(element in self.viewControllers)
{
if([element isKindOfClass:[MainSettingClass class]]){
self.modalTransitionStyle = UIModalTransitionStylePartialCurl;
[self presentModalViewController:element animated:YES]
}
}
}
App is crashing with below Exception.
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Application tried to present modally an active controller .'
* First throw call stack:
NOTE: This not root screen but 3rd sceen of my application.
Base on the debug log you gave I got a reason by searching:
MainSettingClass instance that you pushed before can neither be repushed to the array on navigationController again, nor be presented modally. You should create a new MainSettingClass instance and present it, just like the second code snippet.
HERE is a relate question that mentioned Application tried to present modally an active controller. :)
-(void)popToMainMenuAnimated:(BOOL)animated
{
UIViewController *element;
for(element in self.viewControllers) {
if([element isKindOfClass:[MainSettingClass class]]) {
self.modalTransitionStyle = UIModalTransitionStylePartialCurl;
[self presentModalViewController:element animated:YES];
break;
}
}
}
But why not load the Main Menu instead of pop?
-(void)loadMainMenuAnimated:(BOOL)animated
{
MainSettingClass * mainMenuViewController = [[[MainSettingClass alloc] init] autoreleased];
[mainMenuViewController.view setFrame:CGRectMake(0.0f, 0.0f, 320.0f, 480.0f)];
// ...
self.modalTransitionStyle = UIModalTransitionStylePartialCurl;
[self presentModalViewController:mainMenuViewController animated:YES];
}
And the code you show has some mistakes:
self.modalTransitionStyle= UIModalTransitionStylePartialCurl;
[self popToViewController:element animated:YES];
self.modalTransitionStyle= UIModalTransitionStylePartialCurl; if you set this one, you need use
[self presentModalViewController:yourViewController animated:YES];
not
[self popToViewController:element animated:YES];
It appears that the 'MainSettingsClass' UIViewController you're picking out and attempting to present (modally) is already active. It would help if you put up the code where this view controller may have been previously pushed/presented (and ideally popped/dismissed).
Here are a couple of related questions that might help you.

Removing a view from a SuperView on iOS 4 SDK

I'm developing an iPhone 3.1.3 app with iOS 4 SDK.
I have two ViewControllers, mainViewController and AboutViewController.
I use this code to go from mainViewController to AboutViewController (code inside mainViewController.m):
- (IBAction) aboutClicked:(id)sender
{
AboutViewController* aboutController =
[[AboutViewController alloc]
initWithNibName:#"AboutViewController"
bundle:nil];
[self.view addSubview:aboutController.view];
[aboutController release];
}
And this to come back from AboutViewController to mainViewController (code inside AboutViewController.m):
- (IBAction) backClicked:(id) sender
{
[self.view removeFromSuperview];
}
When I click on Back Button on AboutViewController, I get an EXC_BAD_ACCESS.
I'm using a window-based application template.
I've also tried to add a breakpoint in [self.view removeFromSuperview] but I can't.
Do you know why?
Do this instead:
- (IBAction) aboutClicked:(id)sender
{
AboutViewController* aboutController =
[[AboutViewController alloc]
initWithNibName:#"AboutViewController"
bundle:nil];
[self presentModalViewController:aboutController animated:YES];
[aboutController release];
}
And this to come back from AboutViewController to mainViewController (code inside AboutViewController.m):
- (IBAction) backClicked:(id) sender
{
[[self parentViewController] dismissModalViewControllerAnimated:YES]
}
The reason why you get EXC_BAD_ACCESS is because after adding the view of a viewController as sub view you released the controller, hence the touch event couldn't see the intended viewController to process it.
comment out the release statement like below and it should work
- (IBAction) aboutClicked:(id)sender
{
AboutViewController* aboutController =
[[AboutViewController alloc]
initWithNibName:#"AboutViewController"
bundle:nil];
[self.view addSubview:aboutController.view];
//[aboutController release]; To avoid leaking consider creating aboutController variable at instance level and releasing it in the dealloc.
}
Try:
[self presentModalViewController:aboutController animated:YES];
To present the view and:
[self dismissModalViewControllerAnimated:YES];
To remove the view...
1) Make aboutController a class level variable
2) Create a delegate method to handle
(IBAction) backClicked:(id) sender
3) In implementation of delegate call
[aboutController.view removeFromSuperView];

unable to switch from multiple views

I have a simple app with only location services and 3 (almost empty) different views, and from some reason I can't get from view 1 to view 2 - app crashes and I get an exception. View 1 is the original .xib file, the two others are just views that I added later. It's weird cause I can switch between all of them (1->3, 2->1, 2->3, etc..) just not from 1->2.
I use this code in #1 view controller m. file:
- (IBAction) switchToMaps : (id)sender //this is the one that doesnt work
{
MyMap *mapsView = [[MyMap alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:mapsView animated:YES];
}
- (IBAction) switchToThird : (id)sender
{
ThirdView *third = [[ThirdView alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:third animated:YES];
}
and as another example, here is the code from the 2nd view controller (MyMaps.m):
- (IBAction) switchBack : (id)sender
{
LastLocationViewController *firstView = [[LastLocationViewController alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:firstView animated:YES];
}
- (IBAction) switchFront : (id)sender
{
ThirdView *lastView = [[ThirdView alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:lastView animated:YES];
}
I know it's super vague, but any ideas what can cause this? I have no idea how to debug this...I even put breakpoints at the beginning of each IBAction method, and when it crashes, it doesnt even stop there....before I added this code, this app (which has only location) worked totally fine.
Any ideas?? Thanks!!
if your view does not load from any nib file then you should do like
MyMap *mapsView = [[MyMap alloc] init];
and
ThirdView *lastView = [[ThirdView alloc] init];
and in your back method
- (IBAction) switchBack : (id)sender
{
// LastLocationViewController *firstView = [[LastLocationViewController alloc] initWithNibName:nil bundle:nil]; // because you are allocating new memory to your last view
// [self presentModalViewController:firstView animated:YES];
[self dismissModalViewControllerAnimated:YES];
}
- (IBAction) switchFront : (id)sender
{
// ThirdView *lastView = [[ThirdView alloc] initWithNibName:nil bundle:nil];
// [self presentModalViewController:lastView animated:YES];
[self dismissModalViewControllerAnimated:YES];
}
My hunch is that you're throwing an exception because
MyMap *mapsView = [[MyMap alloc] initWithNibName:nil bundle:nil];
is failing to load a nib. Without seeing your console output it's impossible to say for sure. So a few things to try:
Comment out [self presentModalViewController:mapsView animated:YES];, see if it still crashes.
Explicitly name the nib you expect to load. The nib loader assumes the nib is named exactly the same as the view controller if you pass in nil. So if you don't have a match, you'll end up with an exception (Like this [[MyMap alloc] initWithNibName:#"NibNameWithoutExtension" bundle:nil];)
Set a breakpoint at [self present... and then hover your mouse over "mapsView" after execution pauses. If the popup thing shows you mapsView is nil, you know your trouble is trying to pass a nil object to -presentModalViewController:animated:. If your breakpoint never hits because you throw an exception first, well, there you go, the trouble is a line above.
edit:
One more thing. If your nib has a button that's wired to an action that no longer exists, that would definitely get you in trouble. Inspect each button and make sure no actions are labeled in yellow, indicating a mismatch between the button's target and the actions it's reporting to IB. This would definitely account for the breakpoint behavior you described.

EXC_BAD_ACCESS when calling pushViewController

I have a UITableView inside a UITabBarController.
When I'm calling
[[self navigationController] pushViewController:myViewController animated:YES];
there is no problem.
But, when I'm calling the same line from inside a UIActionSheetDelegate, for example:
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
I get EXC_BAD_ACCESS.
It seems that calling this line from a different thread causing this issue.
How can I prevent this EXC_BAD_ACCESS issue?
(notice that myViewController is NOT nil, or something like that)
thanks!
EXC_BAD_ACCESS is thrown when you try to access a released object, and actionSheet:clickedButtonAtIndex: is called on the main thread, after the action sheet is dismissed, so I'm guessing what's pointed by myViewController is released.
It doesn't have to be nil, in fact, that's the problem. The object pointed is released, but the pointer is not nil.
I just had the same problem and mine was that I did not assine the member varible with self when I alloced it.
This causeed a problem: (myTestViewController is the class member)
TestViewController* test = [[TestViewController alloc] init];
myTestViewController = testViewController;
[testViewController release];
[[self navigationController] pushViewController:myTestViewController animated:YES];
But when I change and assied the class member with self it worked.
TestViewController* test = [[TestViewController alloc] init];
self.myTestViewController = testViewController;
[testViewController release];
[[self navigationController] pushViewController:myTestViewController animated:YES];
I had a similar problem. The way I fixed it was by removing self.navigationController.delegate = self; from my pushed view controller.
tnx.
The UIActionSheet is called from within a class called: MainRootViewController
myViewController is a member in this class (MainRootViewController).
The full code is:
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
myViewController = [[myViewController alloc] init];
[[self navigationController] pushViewController:myViewController animated:YES];
}