14

I'm new to native iOS development, and have been playing with localizing storyboards.

I've been localizing the text for UILabel and UIButton objects in my storyboard by updating the Main.strings files for the storyboard:

// UIButton:
"cEx-Yi-RY8.normalTitle" = "Done";

// UILabel:
"1l2-H9-hRc.text" = "Safety information!";

How do I do the same for a UITabBarItem? I have tried:

//UITabBarItem:
"oSH-y1-hFoB.title" = "Scan";

But it doesn't work :(

I don't get why... I can see it is possible to update the text manually in the UITabBarController:

- (void)viewDidLoad
{
    //...
    item.title = NSLocalizedString(@"scan", nil);
}

But then I have to put those translations in a separate Localizable.strings file, which seems lame.

On the other hand, at least the translations in Localizable.strings are somewhat readable, i.e. "scan" = "Scan"; rather than "oSH-y1-hFoB.title" = "Scan"; ...

Still... I'm not following why some stuff works in Interface Builder but other stuff doesn't and you have to do it manually.

I hate having to add all this boilerplate code to do repetitive stuff like localizing text in the UI, when the framework should just be able to do it for me. (If it can do it for a UIButton, why not a UITabBarItem...)

Or am I just overlooking something?

asgeo1
  • 9,028
  • 6
  • 63
  • 85

4 Answers4

12

You can localize UITabBarItem exactly how you localize other storyboard components. In my opinion, the main reason this doesn't work in your case, is because in a Storyboard you have two title: one on the tab bar, another on the view controller...and you are using the wrong ID :-)

Starting from a new project, tabbed application, click on the project (on the left), the Project (not target) on the right, info tab, add a language in the Localizations (I used Italian). Leave all defaults.

Xcode will create this .strings file for the Italian language:

...
/* Class = "IBUIViewController"; title = "First"; ObjectID = "CZ4-MO-1fc"; */
"CZ4-MO-1fc.title" = "First";

/* Class = "IBUIViewController"; title = "Second"; ObjectID = "QUy-BD-bpt"; */
"QUy-BD-bpt.title" = "Second";

/* Class = "IBUITabBarItem"; title = "Second"; ObjectID = "Z7h-1E-pvt"; */
"Z7h-1E-pvt.title" = "Second";

/* Class = "IBUITabBarItem"; title = "First"; ObjectID = "u1e-5L-l1D"; */
"u1e-5L-l1D.title" = "First";
....

As you can see, there are two titles, one on the VC, another on the TabBarItem. You have to update the titles marked with IBUITabBarItem

shim
  • 9,289
  • 12
  • 69
  • 108
LombaX
  • 17,265
  • 5
  • 52
  • 77
  • Yes, you are correct. I must have been using the wrong ID. But you've also clued me on to something that I didn't realise - when you add the new language, it automatically adds all of the items to the .strings file so you can easily translate them. I didn't understand that, because I had created my localisation files first, before I had created my screens in my storyboard. – asgeo1 Aug 01 '14 at 00:28
  • Looks like here there is a way to "refresh" the localization strings for the storyboard if you did it in the wrong order like I did: http://stackoverflow.com/questions/15094259/is-it-possible-to-update-a-localized-storyboards-strings – asgeo1 Aug 01 '14 at 00:35
11

Another option is to set the titles on the tab bar item to NSLocalizedStrings programmatically.

tabBar.items![0].title = NSLocalizedString("tab1", comment: "")
tabBar.items![1].title = NSLocalizedString("tab2", comment: "")
tabBar.items![2].title = NSLocalizedString("tab3", comment: "")
tabBar.items![3].title = NSLocalizedString("tab4", comment: "")
shim
  • 9,289
  • 12
  • 69
  • 108
Monir Khlaf
  • 567
  • 7
  • 5
4

While you can localize UITabBarItems just like any other StoryBoard component, be aware that if you set a title for the associated view controller, it will overwrite the title of the UITabBarItem. That will prevent your localizations from appearing.

Tad
  • 4,668
  • 34
  • 35
0

obviously you can set it in your view controller. You can set this action in .m file. It also worked if you are using storyboard.

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
    self.tabBarItem.title =NSLocalizedString(@"Alerts",nil);
    }

    return self;
}

or you can also write it in your viewDidLoad method.

self.tabBarItem.title =NSLocalizedString(@"Alerts",nil);

=============== EDIT ================

Let me update for swift with example of storyboard.

Storyboard image

This is out UIStoryBoard TabBarController. And set Identifier for tabbarController in storyboard as

Storyboard identifier

Now in Appdelegate let we set its titles.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.

    let story = UIStoryboard(name: "Main", bundle: nil)
    let tabVC = story.instantiateViewController(withIdentifier: "tabBarController") as! UITabBarController

    let names = [NSLocalizedString("First", comment: "First Tab"), NSLocalizedString("Second", comment: "Second Tab"), NSLocalizedString("Third", comment: "Third Tab")]
    var index = 0
    if let views = tabVC.viewControllers {
        for tab in views {
            tab.tabBarItem.title = names[index]
            index = index + 1
        }
    }

    self.window?.rootViewController = tabVC
    return true
}

And the result is

Simulator image for result

As you can see its showing tab bar titles with updated localised text. And it will set titles at once.

Max
  • 2,269
  • 4
  • 24
  • 49
  • This does not work, at least not in Swift. Apparently, initWithNibName is too early and the value for title gets ignored. On the other hand viewDidLoad is too late if you the view controller is not the first tab. – Banana Jul 01 '19 at 16:38
  • @Banana Yes you are right, That approach will work with xibs, so for storyboard and Latest swift code, I have updated answer which works best for all time. – Max Jul 02 '19 at 04:39