切换语言后重新加载tabBarController

时间:2014-10-31 20:53:59

标签: ios objective-c uinavigationcontroller uitabbarcontroller

在我的应用的设置部分,用户可以选择更改应用的语言。因此,当用户选择 spanish 作为主要语言时,应用会在重新启动应用后显示西班牙语的内容,但我想要动态更改语言 即可。这适用于主要内容,如 TableView ,因为我只是可以重新加载数据,但我的 TabBarController 中的语言不会改变,因为我不知道如何。< / p>

所以我想更新(或者更好地称之为重置) TabBarController 。重置后,它应以新语言显示所有导航点。

我的想法是删除当前的 TabBarController 并初始化一个新的。这可能吗?或者有更好的方法吗?

2 个答案:

答案 0 :(得分:6)

我不是母语为英语的人,所以如果我的解释不够清楚,请告诉我,我会尝试改写它们。

由于我的长篇文章,它可能看起来很可怕和复杂,但它真的不是,它只是很长,因为我认为最好也解释如何做到这一点,而不仅仅是给几行代码。

您可以使用UITabBarController属性实现所需目标。

UITabBarController有一个名为tabBar的属性,即实际的UITabBar 有人可能认为,为了达到你想要的效果,你应该编辑这个属性,
但是,编辑此属性会导致异常 来自apple的UITabBarController文档,关于tabBar属性:

You should never attempt to manipulate the UITabBar object itself stored in  
this property. If you attempt to do so, the tab bar view throws an exception.  

因此,您永远不应该尝试在运行时编辑此属性。

在发出警告之后,这是你应该做的事情 -
UITabBarController还有一个名为viewControllers的属性,它是一个NSArray,它保存对标签栏显示的视图控制器的引用。
可以在运行时修改此属性,并在标签栏中立即更新应用于它的更改 但是,对于您的情况,您不需要修改此属性,
但我认为你应该知道,如果在某些情况下你需要在标签栏中添加或删除一些项目,你就会知道可以做到这一点。

您要做的是迭代该数组的对象以访问视图控制器本身。

UIViewController有一个名为tabBarItem的属性,代表视图控制器的UITabBarItem
所以我们基本上做的是获取视图控制器的标签栏项,但不是从UITabBarController本身获取它,而是直接从每个视图控制器获取它。
每个UITabBarItem都有title属性,这是您想要更改的内容。

所以现在,经过长时间的介绍,让我们来看看实际的代码 我认为实现你想要的一个非常简单的方法是通过viewControllers数组进行迭代,并在那里有一些可以改变标题的switch语句。
与任何编程情况一样,这可以通过无数其他方式完成,因此您可能有比下面的示例更好的方法来实现它,但这应该可以解决问题。

显示在标签栏控制器中的每个视图控制器都使用属性tabBarController对该标签栏进行引用 因此,您可以在选项卡栏中显示的任何视图控制器中运行此代码,只需使用self.reference来获取对它的引用。

在语言发生变化后将其添加到某处 -

for (int i = 0; i < [self.tabBarController.viewControllers count]; i++) {  
    if([self.tabBarController.viewControllers[i] isKindOfClass: [UIViewController class]]) {  
        UIViewController *vc = self.tabBarController.viewControllers[i];  
        switch(i) {  
            case 0:  
                vc.tabBarItem.title = @"primero";  
                break;  
            case 1:  
                vc.tabBarItem.title = @"secondo";  
                break;  
        }  
    }  
}

我们基本上正在做的是运行一个for循环,循环遍历数组中的所有项目,
数组中的项目与它们在选项卡栏上显示的顺序相同,
然后我们使用switch语句来改变视图控制器在相应位置的标题,
由于数组的索引为0,因此第一个视图控制器位于i = 0的位置,最后一个视图控制器的位置小于数组中项目的数量。
有些人可能认为我的if是不必要的 由于我们已经知道此数组仅包含视图控制器,因此无需检查该位置的项是UIViewController类还是其子类。
他们可能是对的,但我总是说安全比抱歉更好。

诅咒我还会在你的代码中包含一些实际检查用户选择的语言的内容 无论用户选择什么,上面的示例都会将标题更改为西班牙语。

希望它有助于交配,
祝你好运

答案 1 :(得分:0)

@ AMI289提供了一个好主意。

对UITabBarController进行扩展,并在那里进行循环。可以从tabBarControllers堆栈中的任何位置调用。

在我的情况下,tabBarController进入了NavigationController。

//  MARK: - UITabBarController
extension UITabBarController {
    func changeTitleLocale() {
        guard let viewContollers = self.viewControllers else { return }
        for (index, navVC) in viewContollers.enumerated() {
            if let view = navVC as? UINavigationController {
                if let topView = view.topViewController {
                    if topView.isKind(of: ProfileVC.self) {
                        self.tabBar.items?[index].title = "tab_profile"
                    } else if topView.isKind(of: ChatVC.self) {
                        self.tabBar.items?[index].title = "tab_chat"
                    } else if topView.isKind(of: PicturesVC.self) {
                        self.tabBar.items?[index].title = "tab_pictures"
                    } else if topView.isKind(of: VideosVC.self) {
                        self.tabBar.items?[index].title = "tab_videos"
                    }
                }
            }
        }
    }
}

然后,当我们更改语言时,只需运行它即可:

self.tabBarController?.changeTitleLocale()