强制本地化内部框架,如UIKit,无需重启App

时间:2018-01-29 10:01:42

标签: ios swift localization uikit

我必须在应用程序中添加一个切换语言的选项。 我只是坚持本地化内部framworks。任何人都可以帮助我从应用程序本身的内部框架本地化,如UIKit等,而无需重新启动。我的代码工作正常,但对于内部框架的情况需要重新启动。只是内部框架没有得到本地化。

我目前的代码是:

创建一个名为BundleExtension.swift的文件,并将以下代码添加到其中 -

var bundleKey: UInt8 = 0

class AnyLanguageBundle: Bundle {

override func localizedString(forKey key: String,
                              value: String?,
                              table tableName: String?) -> String {

    guard let path = objc_getAssociatedObject(self, &bundleKey) as? String,
        let bundle = Bundle(path: path) else {

            return super.localizedString(forKey: key, value: value, table: tableName)
    }

    return bundle.localizedString(forKey: key, value: value, table: tableName)
  }
}

extension Bundle {

class func setLanguage(_ language: String) {

    defer {

        object_setClass(Bundle.main, AnyLanguageBundle.self)
    }

    objc_setAssociatedObject(Bundle.main, &bundleKey,    Bundle.main.path(forResource: language, ofType: "lproj"), .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
  }
}

现在,无论何时需要更改语言,都可以调用此方法:

func languageButtonAction() {
    // This is done so that network calls now have the Accept-Language as "hi" (Using Alamofire) Check if you can remove these
    UserDefaults.standard.set(["hi"], forKey: "AppleLanguages")
    UserDefaults.standard.synchronize()

    // Update the language by swaping bundle
    Bundle.setLanguage("hi")

    // Done to reintantiate the storyboards instantly
    let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
    UIApplication.shared.keyWindow?.rootViewController = storyboard.instantiateInitialViewController()
}

4 个答案:

答案 0 :(得分:3)

查看此演示,它将适合您。

Link

答案 1 :(得分:0)

你的代码似乎很好,但我尝试过的是......

从应用程序更改语言时......

Bundle.setLanguage("fr")
UserDefaults.standard.set(["fr"], forKey: kAppleLanguages)
UserDefaults.standard.synchronize()

NotificationCenter.default.post(name: NSNotification.Name.init("AppLanguageChangeNotification"), object: nil)

因此,每当语言发生变化时,都会触发此通知,并且会通知添加观察者的视图控制器,并根据该语言进行更改。

添加观察者

NotificationCenter.default.addObserver(viewController, selector: #selector(self.setLocalization), name: NSNotification.Name.init("AppLanguageChangeNotification"), object: nil)

方法

@objc fileprivate func setLocalization() {

    self.lblProfile.text = NSLocalizedString("lblProfile", comment: "")
    self.lbDetails.text = NSLocalizedString("lblDetails", comment: "")
    .
    .
}

是的,这是位日志过程,因为您需要让所有IBOutles设置本地化文本。

答案 2 :(得分:0)

这取决于您想要本地化的特定框架。需要知道此框架从何处获取其本地化。对于大多数情况来说,这是不可能的,因为你必须硬编码框架的本地化文件的路径,或者知道一些破坏框架思想的框架:对实现知之甚少,你应该知道的只是接口。 / p>

要实现您的目标,您应该拥有本地化的唯一来源。

使用pod或其他非系统框架,您可以将它们分叉并进行更改,以便将字符串传递给它。

使用系统库可能是不可能的,因为没有机会以某种方式改变它。但是我知道的所有情况都可以在这些系统库的帮助下实现,例如,我正在谈论本地化的导航栏按钮。您可以创建自己的按钮并将其标题设置为您想要的任何内容。

希望它有所帮助。如果没有,那么您可以展示您无法本地化的示例,我会尽力帮助您。

答案 3 :(得分:0)

我遇到了同样的问题,只有我的解决方案才能完全重新加载所有UIViewController