App crashes when transitioning between tabs, EXC_BAD_ACCESS - iphone

I could use some help debugging this issue if anyone has had experience with it. I have a UITabBarController as my root view controller. The first view controllers of each tab are UINavigationController.
Tab 1:
A view with a map is the first viewController.
When you push on the callout, this code is run:
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control {
[self performSegueWithIdentifier:#"ShowLocationDetails" sender:self];
}
In the storyboard, I have this wired up as Push.
On the first viewController, because I have a map and don't want to have a navigation bar show, I do this:
FirstViewController <UINavigationControllerDelegate>
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
[self.navigationController setNavigationBarHidden:YES animated:NO];
}
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
[self.navigationController setNavigationBarHidden:YES animated:NO];
}
On the second view controller that I push onto the stack, I do want the navigation bar, so I have this code:
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
if ([viewController isKindOfClass:[FirstViewController class]]) {
[self.navigationController setNavigationBarHidden:YES animated:YES];
}
else {
[self.navigationController setNavigationBarHidden:NO animated:YES];
}
}
Tab 2:
Just a tablview for right now.
I can get my app to crash if I do these simple steps:
Press the callout to push the LocationDetails.
Press back to go back to First View Controller
Press tab two to go to a TableViewController
Press tab one to go back to the map and this crashes it with an EXC_BAD_ACCESS. I tried running Instruments, but I didn't know what it meant:
If I start the app, and just switch between the tabs all day without pushing a new controller onto the stack on tab 1, it does NOT crash.
It also does not crash if I remove the navigationController willShowViewController delegate methods. But of course then I have the navigation bar which is not what I want.
Any thoughts? Thanks!
EDITED
So I tried what Nuzhat said and I get the same problem. I tried both
self.navigationController.navigationBar.hidden = YES;
and
self.navigationController.navigationBardHidden = YES;
and it isn't the solution I"m looking for. What happens is when I push to the next view controller the navigationBar is not there. So in that viewController's viewDidLoad, I set
self.navigationController.navigationBar.hidden = NO;
Then I pop back to FirstViewController, then I switch tabs, still crashes. There seems to be a problem with hiding the navigation bar, and then showing it again.

Related

Calling poptoviewcontroller function from a viewcontroller

Let me explain clearly.
I have a tabbarcontoller in the viewcontroller which is the main view controller of the single view application project.
I added a tabbarcontroller to the viewcontroller as the subview. In the tabbarcontroller, I added two navigation controllers like below image,
I have added three(named First, Second, Third) more viewcontrollers as new file.
If I navigate from one viewcontroller to other in a tab using below,
third = [[Third alloc] initWithNibName:#"Third" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:third animated:YES];
If I switch to next tab and come back to the previous tab, it should popto the previous view controller, how to do this?
I tried
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:0] animated:YES];
}
not succeed,
I also tried,
[third popto];
In the third viewcontroller,
-(void)popto
{
[self.navigationController popViewControllerAnimated:YES];
}
nothing happened.
Now, I have to click the tab again to poptoviewcontroller to the first viewcontroller.
Any ideas will be highly appreciated.
You should try using
[viewController.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:0] animated:YES];
instead of
[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:0] animated:YES];
Try the below code snippet
-(BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
{
UINavigationController *navController = (UINavigationController*)viewController;
if (navController && ([[navController viewControllers] count] > 0))
{
[navController popToRootViewControllerAnimated:NO];
}
return YES;
}
Hope it may work for you.
How about overriding UITabbarController for a custom one and implement the following method:
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController;
Next loop trough all the 'viewcontrollers' of the tabbar (in this case the navigation controllers) and call on all the navigation controllers popToRootViewController.
This might work.

resetting to first view controller when tabbaritem is selected

I have a tab bar with 3 items. Each points to a UINavigationController. Each UINavigationController has several viewControllers beneath. I'm wanting to reset back to the first controller in the navigation when any tab bar item is pressed.
I've specified my TabBarController implementation as a delegate
self.delegate = self and my method below (running in my TabBarController implementation works returning UINavigationControllers.
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
NSLog(#"%#", viewController);
}
With the log file showing e.g.
UINavigationController: 0x8a31a90>2012-12-31 02:16:40.035 Demo[6142:c07]
when I try popToRootViewController or popViewController within this method it doesn't seem to work. I don't get any errors but my viewControllers don't reset. It seems like I've made a really basic error here but I can't tell what.
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
NSLog(#"%#", viewController);
[self.navigationController popToRootViewControllerAnimated:YES];
[[self navigationController] popViewControllerAnimated:YES];
}
You need to popToRootViewController on the navigationController (viewcontroller) - not the TabViewController (self).
[viewController popToRootViewControllerAnimated:YES];
I'm not sure if this will help. I had a lot of trouble getting this to work and found that I needed to do the following:
In root view controller (first view app comes to), add a delegate in the .h file.
#interface MGMProductsViewController : UIViewController <UITabBarControllerDelegate>
Add the below code to viewDidLoad in root view controller (.m file).
[self.tabBarController setDelegate:self];
Override method in root view controller (.m file) with the below.
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
if ([viewController isKindOfClass:[UINavigationController class]])
{
[(UINavigationController*)viewController popToRootViewControllerAnimated:NO];
}
}
I can't attribute this to anyone as I couldn't find the appropriate code again. I think I pieced it together from a few places though the '[self.tabBarController setDelegate:self]' looked to be the key to it working for me.
Good luck.

Return to first view in UITabBarItem

When I receive a Push Notification, I want to jump to the middle tab on the tabbar and reset the tab (it has multiple table views that the user may have navigated into). I am able to jump to the tab using tabBarController.selectedIndex = 1; ... but how do I reset to the first view?
Implement UITabBarControllerDelegate on a controller class (perhaps your app delegate) and implement tabBarController:didSelectViewController: to pop all pushed view controllers off the navigation stack:
- (void) tabBarController:(UITabBarController *) tabBarController didSelectViewController:(UIViewController *) viewController {
if([viewController isKindOfClass:[UINavigationController class]])
{
[(UINavigationController *)viewController popToRootViewControllerAnimated:YES];
}
}

navigation bar is visible when i navigate back to main view

i am using this in my view didlod
[self.navigationController setNavigationBarHidden:YES];
it hides when applicationn launches but when i navigate to next screen and come back to main view is not hide it navigation bar...
why is it like that?
should i add any thing ?
....
This works for me:
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:YES animated:animated];
}
- (void) viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.navigationController setNavigationBarHidden:NO animated:animated];
}
You wouldn't then need the one in viewDidLoad.
If it's not clear from that change, the reason your original code didn't work is that the view may be kept in memory even if it is not on screen - so need to hide / display the navigation bar each time the view is brought on or off screen.
viewDidLoad only fires the first time it loads your view. viewWillAppear fires every time.

How to reset a uinavigationview to display the root controller when user clicks back to it in a tab bar app

How to reset a uinavigationview to display the root controller when user clicks back to it in a tab bar app
Hey,
Just wondering how I would do this. I have the navcontroller in my delegate along with the tabbar controller and Any time the user clicks to another tab I want the rootview on the navigation controller to be shown if and when they click back the the tab that contains the uinavcontroller.
Does this make sense?
Nick
[self.navigationController popToRootViewControllerAnimated:YES];
Or NO if you don't want it to animate.
This way all the views that were cached are still there, i.e. you don't "remove/release" all the views above the root view, unless the navigationController deems it necessary.
I hope this was what You were looking for..
place the code in appdelegate.m
if ([viewController isKindOfClass:[UINavigationController class]]) {
UINavigationController *nav = (UINavigationController *)viewController;
[nav popToRootViewControllerAnimated:NO];
}
When using the UITabBar delegate method, you must delay the popToRootViewControllerAnimated call.
-(void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item
{
if ([self.selectedViewController isKindOfClass:[UINavigationController class]]) {
UINavigationController *view=(UINavigationController *)self.selectedViewController;
[view performSelector:#selector(popToRootViewControllerAnimated:) withObject:nil afterDelay:.5];
}
}