12

This application I'm writing has a problem.

I'm setting up the UITabBar in my application window and set the icons in the view files. But when i run the app, the first icons show up (because the view is loaded I guess) and the other icons do not show up until I click them.

Do i need to implement self.tabBarItem in some other method not viewDidLoad?

Thanks in advance to everyone!

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
    tabBar = [[UITabBarController alloc] init];

    SubscriptionsController *subscriptionsController = [[SubscriptionsController alloc] init];
    FavoritesController  *favoritesController  = [[FavoritesController  alloc] init];
    CategoriesController *categoriesController  = [[CategoriesController alloc] init];
    TagsController   *tagsController    = [[TagsController   alloc] init];
    HelpScreenController *helpScreenController  = [[HelpScreenController alloc] init];

    tabBar.viewControllers = [NSArray arrayWithObjects:
        subscriptionsController, 
        favoritesController, 
        categoriesController, 
        tagsController, 
        helpScreenController, 
        nil
        ];

    [window addSubview:tabBar.view];

    // Override point for customization after application launch.
    [window makeKeyAndVisible];
    return YES;
}

//The View

- (void)viewDidLoad {
    [super viewDidLoad];
    tabIcon = [[UITabBarItem alloc] initWithTitle:@"Abonime" image:[UIImage imageNamed:@"subscr.png"] tag:0];
    self.tabBarItem = tabIcon;
    [tabIcon release];
}
Eric O. Lebigot
  • 91,433
  • 48
  • 218
  • 260
Olsi
  • 929
  • 2
  • 12
  • 26

2 Answers2

14

I think you should set the tabBarItem property in a view controller's designated initializer (judging from your code, it must be -init for each of the controllers). In fact, the tab bar controller is smart enough to load the views on demand, that is, the tabBarItem property should be set before viewDidLoad gets sent.

Also, you seem to be leaking all the view controllers. To fix that, do the following:

SubscriptionsController *subscriptionsController = [[[SubscriptionsController alloc] init] autorelease];
Costique
  • 23,712
  • 4
  • 76
  • 79
  • How do I do this in swift 2? – deepakssn Oct 27 '15 at 06:22
  • I've been looking at this answer but still need some more specifics. Can you please give a complete answer in Swift 4? Thanks :) – Andy Lebowitz Dec 11 '18 at 21:35
  • @AndyLebowitz The issue has actually nothing to do with the language you use. You should make sure you assign `tabBarItem`s to your view controllers **before** you configure your `UITabBarController` with those view controllers, because in order to display the tab bar items `UITabBarController` needs to access the `tabBarItem` property of its child view controllers. When the child view controllers receive `viewDidLoad`, the tab bar items should have already been displayed, so it's too late to set `tabBarItem` in `viewDidLoad`. I hope this clears things up a bit. – Costique Dec 14 '18 at 10:55
4

Correct. The icons don't show up because the view (other than the first one, isn't loaded yet). And doesn't get loaded until you tap a view because viewDidLoad isn't called until then.

Remove the code in the individual UIViewControllers viewDidLoad and Do this...

NSArray *controllers = [NSArray arrayWithObjects:
                                                [NSDictionary dictionaryWithObjectsAndKeys:@"SubscriptionsController", @"class", [UIImage imageNamed:@"btn_tax.png"], @"icon", @"Abonime", @"title", nil],
                                                [NSDictionary dictionaryWithObjectsAndKeys:@"FavoritesController", @"class", [UIImage imageNamed:@"btn_tax.png"], @"icon", @"Abonime", @"title", nil],
                                                [NSDictionary dictionaryWithObjectsAndKeys:@"CategoriesController", @"class", [UIImage imageNamed:@"btn_tax.png"], @"icon", @"Abonime", @"title", nil],
                                                [NSDictionary dictionaryWithObjectsAndKeys:@"TagsController", @"class", [UIImage imageNamed:@"btn_tax.png"], @"icon", @"Abonime", @"title", nil],
                                                [NSDictionary dictionaryWithObjectsAndKeys:@"HelpScreenController", @"class", [UIImage imageNamed:@"btn_tax.png"], @"icon", @"Abonime", @"title", nil],
                                                nil];

NSMutableArray *controllerArray = [NSMutableArray array] ;

 for (NSUInteger i = 0; i < [controllers count]; i++)
 {
    id newClass = [[NSClassFromString([[controllers objectAtIndex:i] objectForKey:@"class"]) alloc] init];
    UITabBarItem *tabItem = [[UITabBarItem alloc] init];
    tabItem.image = [[controllers objectAtIndex:i] objectForKey:@"icon"];
    tabItem.title = [[controllers objectAtIndex:i] objectForKey:@"title"];
    tabItem.tag = i;
    [(UIViewController*)newClass setTabBarItem:tabItem];
    [tabItem release];
    [controllerArray addObject:newClass];
    [newClass release];
 }

 tabBar.viewControllers = controllerArray;
Jordan
  • 21,746
  • 10
  • 51
  • 63