1

I have a UINavigationController(a) that pushes a UIViewController(b) onto the stack. (b) contains a UITabBarController(c). (c) has 5 tabs and any of these ViewControllers(d,e,f,g,h) needs to be able to pop (b) off the stack.

I've tried [[self.parentViewController navigationController] popViewControllerAnimated:YES]; among many other things, none of which seem to work. Any ideas?

Edit:

.h file:

@interface MATabViewController : UIViewController<UITabBarControllerDelegate> {
UIViewController *ref;
}

@property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
@property (nonatomic, retain) IBOutlet UIImageView *imgViewFooter;

@end

.m:

#import "MATabViewController.h"

@implementation MATabViewController
@synthesize tabBarController = _tabBarController;
@synthesize imgViewFooter;

- (void)viewDidLoad
{
[super viewDidLoad];

self.view = self.tabBarController.view;

self.tabBarController.delegate = self;
self.imgViewFooter.frame = CGRectMake(0.0f, 395.0f, 320.0f, 64.0f);
[self.tabBarController.view addSubview:self.imgViewFooter];
self.tabBarController.selectedIndex = 0;

ref = [[self.tabBarController viewControllers] objectAtIndex:0];
}

-(BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController {

NSInteger index = [[tabBarController viewControllers] indexOfObject:viewController];

switch (index) {
    case 0:
        self.imgViewFooter.image=[UIImage imageNamed:@"footer_full.png"];
        break;
    case 1:
        self.imgViewFooter.image=[UIImage imageNamed:@"footer_full.png"];
        break;
    case 2:
        self.imgViewFooter.image=[UIImage imageNamed:@"footer_full.png"];
        break;
    case 3:
        self.imgViewFooter.image=[UIImage imageNamed:@"footer_full.png"];
        break;
    case 4:
        self.imgViewFooter.image=[UIImage imageNamed:@"footer_full.png"];
        break;

    default:
        break;
}
return YES;
}

-(void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
if (ref != viewController) {
    [ref viewDidDisappear:YES];
    ref = viewController;
    [viewController viewDidAppear:YES];
}
}

@end

notice how I have a major hack in this line:

self.view = self.tabBarController.view;
Lance
  • 8,872
  • 2
  • 36
  • 47
  • 1
    Do you mean you want to pop back to (a) from (d-h)? If so, `[self.navigationController popToRootViewControllerAnimated:YES]` should do the trick since all of the views should inherit the same navigation controller as they are in the root's stack – justin Jul 20 '11 at 20:28
  • yea, that does not work, unfortunatly... I just tried it. I think (b) needs to call it but I can't seem to get it to... – Lance Jul 20 '11 at 20:33
  • This is just a guess, but `[[[[self.tabBarController parentViewController] navigationController] popViewControllerAnimated:YES]` might be a more direct route. It pretty much tells the (d-h) view controllers to call their parent tabBarController, which then calls its parent, then the nav controller – justin Jul 20 '11 at 20:37
  • thanks for the reply, but it still doesn't work... :( – Lance Jul 20 '11 at 21:14
  • What you are trying to achieve is not good app design. Who calls popViewController? I'm guessing there's a back button in each view controller's view of your tab bar, right? Suppose the user has been switching tabs -- he might think that the back button is going to lead him into the previously selected tab, don't you agree? Even if you find a way to get this to work, I suggest you find an alternative way to organize your interface. – MiguelB Jul 20 '11 at 21:54
  • @miamk There may be situations in which this design has sense, though. Think about a home view and a control panel (with multiple settings). You can use a navigation controller to navigate from home to control panel and back, while the tab bar can let you navigate among the control panel's views. This case it's pretty obvious that the back button in the navigation bar won't show the last view selected but will bring you to the home view. I won't say it's not a good design, I'd rather say that it depends :) – Manlio Jul 20 '11 at 23:04
  • @miamk thanks for the answer, but without seeing the actual app, how can you make the assumption that it is a bad app design? – Lance Jul 21 '11 at 14:49
  • Because a Tab Bar Controller is a higher hierarchy controller than a Navigation Controller. That's what the user expects (and Apple as well, check out the HIG). You are essentially inverting the expected hierarchy. But you are right, I have not seen your app. And picking up what @Saphrosit said, if you have a good sense about it, it might actually work. Although I have my doubts the way you described it. I'm just giving you a heads up. Cheers. – MiguelB Jul 21 '11 at 21:24
  • @Lance, still on that Nav/Tabbar controller debate, I suggest you check this answer to a question posted today: http://stackoverflow.com/questions/6859868/popping-viewcontroller-doesnt-call-viewwillappear-when-going-back/6859964#6859964 – MiguelB Jul 28 '11 at 13:59
  • Actually, I think it might even explain your original question. – MiguelB Jul 28 '11 at 14:18

1 Answers1

2

I experienced a similar problem (if I get the question). May you declare your UIViewController (b) as a subclass of UITabBarController? Notice that UITabBarController is a subclass of UIViewController, so you can keep using it as a normal UIViewController. This way you'll have (b) and (c) in a single controller.
Now [self.navigationController popViewController]; should work.
At least, that's the way I solved it.

Manlio
  • 10,768
  • 9
  • 50
  • 79
  • This seems like the best solution, could you go into more detail on how to accomplish this? I'll update my question with code from UIViewController(b) – Lance Jul 21 '11 at 14:51
  • in .h simply declare your MATabViewController as a subclass of UITabBarController (the protocol is ok, no need to change it), and remove the @property statement of *tabBarController. In .m remove remove the @synthesize statement and, in viewDidLoad, replace `self.tabBarController` with simply `self` (that's because self IS a tabBarController). Didn't try it, but it should work. – Manlio Jul 21 '11 at 23:53
  • Seems like `[self.navigationController popViewControllerAnimated:true];` is the way to do it now (iOS 5.1). Or `[self.navigationController popToRootViewControllerAnimated:true];` depending on how far you want to go. – drewish Jun 14 '12 at 21:30