在Storyboard中自动本地化UITabBarItem文本是否可行?

14

我刚开始接触原生iOS开发,并尝试对Storyboard进行本地化。

我一直在通过更新Storyboard对应的Main.strings文件来本地化UILabelUIButton对象的文本:

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

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

我该如何对 UITabBarItem 进行相同的操作?我尝试了:

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

但它不起作用 :(

我不明白为什么... 我可以看到在UITabBarController中手动更新文本是可能的:

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

但是我必须将这些翻译放在单独的Localizable.strings文件中,这似乎很不好。

另一方面,至少Localizable.strings中的翻译有点可读性,例如"scan" = "Scan";而不是"oSH-y1-hFoB.title" = "Scan"; ...

尽管如此...我还是不明白为什么有些东西可以在Interface Builder中工作,而其他东西则不能,必须手动完成。

我讨厌添加所有这些样板代码来执行诸如本地化UI中的文本之类的重复性任务,因为框架应该只需能够为我完成它。(如果它可以为UIButton做到这一点,那为什么不能为UITabBarItem做到呢......)

或者我是不是忽略了什么?

4个回答

12
您可以像本地化其他Storyboard组件一样精确本地化UITabBarItem。在我看来,这不起作用的主要原因是因为在Storyboard中,您有两个标题:一个在标签栏上,另一个在视图控制器上...而您正在使用错误的ID :-)
从新项目开始,选项卡应用程序,单击左侧的项目,右侧的项目(而不是目标),信息选项卡,在本地化中添加一种语言(我使用了意大利语)。保留所有默认值。
Xcode将为意大利语创建此.strings文件:
...
/* 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";
....

正如您所见,有两个标题,一个在 VC 上,另一个在 TabBarItem 上。 您需要更新标有IBUITabBarItem的标题。


是的,你说得对。我一定使用了错误的ID。但你也让我意识到了一些事情 - 当你添加新语言时,它会自动将所有项目添加到.strings文件中,以便你可以轻松地进行翻译。我之前并没有理解这一点,因为我先创建了本地化文件,然后才在storyboard中创建了屏幕。 - asgeo1
看起来这里有一种方法可以“刷新”故事板的本地化字符串,如果您像我一样按错误顺序执行了它:https://dev59.com/gWUp5IYBdhLWcg3wvZRV - asgeo1

11

另一个选项是通过编程方式将选项卡栏项目的标题设置为NSLocalizedString。

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: "")

4

虽然您可以像对待任何其他StoryBoard组件一样本地化UITabBarItem,但请注意,如果为关联的视图控制器设置了标题,则它将覆盖UITabBarItem的标题。这将防止您的本地化内容显示。


这正是我的问题,感谢提供信息。 - alierdogan7

0

显然,您可以在视图控制器中设置它。您可以在.m文件中设置此操作。如果您正在使用故事板,则它也可以工作。

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

    return self;
}

或者你也可以在viewDidLoad方法中编写它。

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

=============== 编辑 ================

让我用Storyboard的示例来更新Swift。

Storyboard image

这是我们的UIStoryBoard TabBarController。 在故事板中为tabbarController设置标识符。

Storyboard identifier

现在在Appdelegate中让我们设置它的标题。

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
}

结果是:

Simulator image for result

正如你所看到的,它展示了带有更新本地化文本的选项卡栏标题。而且它会一次性设置所有标题。


这在Swift中不起作用。显然,initWithNibName太早了,title的值被忽略了。另一方面,如果视图控制器不是第一个选项卡,则viewDidLoad太晚了。 - Banana
@Banana 是的,你说得对。这种方法适用于xibs,但是对于storyboard和最新的Swift代码,我已经更新了答案,这是最好的解决方案。 - Max

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接