38

I have a TabBarController set as main controller tab, where names were defined using interface builder. Now I would like to change its names programmatically.

How could it be done?

Kheldar
  • 5,361
  • 3
  • 34
  • 63
Ruth85
  • 645
  • 2
  • 7
  • 12

7 Answers7

51

Updated to XCode 8

Since my original answer, a lot has happened: Swift 3, Storyboards, etc. Title is usually the one that all views share, and can be set in the attributes inspector

Title Setup

Also, for more control, you can always drag the UITabBarItem, and UINavigationItem elements from the designer view. You must drag them to the view that's gonna be displayed in the tab bar/navigation controller. Basically they store the info as "I wanna be displayed in tab bar like this".

enter image description here

Hello Scene is getting a TabBarItem added to it, so it can be configured.

These two elements behave exactly as accessing the view controller's .tabBarItem and .navigationItem properties via code. These properties always exist in code if they are child of the corresponding object (nav has navItem, and tab has tabItem), you don't need to add them in storyboard/xib to have them.

This last thing is kinda confusing, since in the storyboard/xib it appears you're adding them to the view controller, but in truth you're just saying "the nib will configure these properties too".

Original Answer

The name that appears on the tab bar comes from the UIViewController's title property,

self.title = @"Name me!";

You can change the title at any point, and it should update the text appearing on the tab bar item. But be wary, do this as soon as possible, ideally, in the init method in use (or initWithNibName:bundle:, or initWithCoder:).

The key here, is that the init methods are called as soon as the tab bar appears on screen, as it initialises all of its view controller. If you were to do it on viewDidLoad, that would only get called if you actually select the tab, then other family of calls, same goes for awakeFromNib, viewWillAppear:, viewDidAppear:, etc.

The idea of having a title on the UIViewController, is to keep things consistent. If you show that viewController on a UINavigationController, the navigation bar on top should use the title property, as it does when using back. The UITabBarController also respects the same title property and changes accordingly.

In terms of reusability, you should be setting the title only from the inside of the UIViewController subclass.

The way of the Nib

Using nibs or storyboards? If you have a UIViewController, you can give it the name straight up in the attributes inspector (or 4)

Using interface builder, in the Attributes Inspector

Unfortunately, if the File Owner is the UIViewController subclass, then you won't be able to access it this way, simply because, XCode registers the File Owner as an "External Object", and doesn't show a configuration panel for it. :(

Multiple titles, same view controller

But sometimes, you just want to have them named differently

// Modify the display title on the tab bar
self.tabBarItem.title = @"World";

// Modify the display title on the navigation bar
self.navigationItem.title = @"Hello World";

Screwing with the neighbours

Each UIViewController should handle his own name, what if you want to force it from the outside (and thus, completely violating the original thing I said about reusability)?

// Rename the other guy's .title property
[[self.tabBarController.viewControllers objectAtIndex:<#Index#>] setTitle:@"Hello World"];

// Or do as before, and rename the other guy's tab bar 
[(UITabBarItem*)[self.tabBarController.tabBar.items objectAtIndex:<#index#>] setTitle:@"Hello World"];

You could also probably do it with the navigation item, but that would require more gymnastics than I'm comfortable with.

Can
  • 8,502
  • 48
  • 57
  • I already try it and it does not generate any error. However it is not working, tab name remains the same. – Ruth85 Aug 31 '11 at 08:49
  • 3
    The `self.tabBarItem.title` solution does not work for me either, but the other one does: `[[self.parentViewController.tabBarController.tabBar.items objectAtIndex:4] setTitle:@"NewTitle"];` – dchakarov Nov 10 '11 at 20:36
  • Multiple titles, same view controller section helped me a lot. thank you my friend – smoothumut Jan 13 '15 at 08:44
  • FWIW, I had to modify the parentViewController's tabBarItem rather than the view controller's itself – rounak Jul 22 '15 at 16:50
38

However it is possible to do it in code, it is better to set this directly in Storyboard. How?

Just tap the appropriate tab bar item inside controller (NOT INSIDE TABBAR CONTROLLER).

enter image description here

Then switch to attribute inspector on the Utilities panel.

enter image description here

Now you are able to change everything:-)

Bartłomiej Semańczyk
  • 59,234
  • 49
  • 233
  • 358
9

Swift 4+

tabBarController?.tabBar.items![1].title = "xx"
Ahmadreza
  • 6,950
  • 5
  • 50
  • 69
2

In your viewController.m

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
  //Here you are setting title

self.title = NSLocalizedString(@"Title", @"Title");

}
return self;
}
Stephan
  • 41,764
  • 65
  • 238
  • 329
1

You probably want to do this in UITabBarController::viewDidLoad in which case you need to set the view controller's title because the tab bar items are currently 0 at that point. So use

[[self.viewControllers objectAtIndex:0] setTitle: @"Buga"];
[[self.viewControllers objectAtIndex:1] setTitle: @"Nuga"];
RelativeGames
  • 1,593
  • 2
  • 18
  • 27
  • 1
    I am not understand for why your answer didn't accept..it's really awesome answer! Thanks! You are saved my time! – Genevios Jun 13 '17 at 13:32
1

This is how you can change the name and the image of the icon of a tab bar:

 self.tabBarItem = [[[UITabBarItem alloc] initWithTitle:@"Main Tab" image:[UIImage imageNamed:@"maintab.png"]] autorelease];
TommyG
  • 4,145
  • 10
  • 42
  • 66
  • 1
    Be careful there, you're not releasing the new UITabBarItem, either append a `[ autorelease]`, or create a new one with, add it, and then release it. – Can Aug 30 '11 at 22:31
  • 1
    Thanks, I changed it. I am using ARC so did not have it. – TommyG Aug 30 '11 at 22:34
  • 1
    There's no need to create a new one. This is a bad solution with or without a memory leak. – Erik B Aug 30 '11 at 22:37
-2

I'm using Xcode Version 8.2.1 (8C1002) and this works for me:

enter image description here

Sebastián Lara
  • 5,355
  • 2
  • 28
  • 21