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

Posted

技术标签:

【中文标题】强制本地化 UIKit 等内部框架,无需重启 App【英文标题】:Force Localize Internal Frameworks like UIKit without App restart 【发布时间】:2018-01-29 10:01:42 【问题描述】:

我只需要在应用程序内添加一个切换语言的选项。 我只是坚持本地化内部框架。任何人都可以帮助我从应用程序本身本地化 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()

【问题讨论】:

【参考方案1】:

查看这个演示,它会为你工作。

Link

【讨论】:

我正在使用相同的。刚把它移植到swift。工作完美。只是内部库没有在旅途中本地化。为此需要重启应用。 您还有什么建议吗??【参考方案2】:

您的代码看起来不错,但我尝试过的是......

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

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 来设置本地化文本。

【讨论】:

正如我所说,我的本地更改没有任何问题。它与系统库(如 UIKit)和未更新的 pod 相关包一起使用。【参考方案3】:

这取决于您要本地化的特定框架。这需要知道该框架从何处获得其本地化。在大多数情况下,这是不可能的,因为您必须对框架的本地化文件的路径进行硬编码,或者对框架有所了解,这会破坏框架的一个理念:对实现知之甚少,您应该知道的只是接口。

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

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

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

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

【讨论】:

【参考方案4】:

我遇到了同样的问题,对我来说唯一的解决方案是完全重新加载所有UIViewController

【讨论】:

只是内部库没有在旅途中本地化。为此需要重新启动应用程序。示例 UIImagePicker 上的内容不会被本地化。 @ankit 您是否找到任何解决方案来更新 UIImagePicker 等内部库以进行本地化? 不,Aman 还没有。我什至已经邮寄并使用了开发者帐户附带的 Apple 技术支持,但我仍然没有得到任何回复。如果您发现任何问题,请告诉我,即使是 hack 也可以。

以上是关于强制本地化 UIKit 等内部框架,无需重启 App的主要内容,如果未能解决你的问题,请参考以下文章

如何在我的应用程序中使用 UIKit 本地化字符串

UIKit框架框架简介

Windows10安装Au后,进入软件会提升mee设备内部错误,并且,点击播放后au会强制弹出?

UIKit框架(17)Quartz2D

iOS UIKit框架

Vue与UIKit集成