强制本地化 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的主要内容,如果未能解决你的问题,请参考以下文章