ios Swift:如何更改应用程序内的语言?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37111409/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 09:01:23  来源:igfitidea点击:

Swift : How to change language inside app?

iosobjective-cxcodeswiftlocalization

提问by KababChi

i am using Localize-Swiftlibrary (Link) to localize my application and it works fine with .strings files. the problem is that i have to localize to a language which is right to left and i have to localize via Interface Builder Storyboard so i can make view controllers look right in RTL format. the question is how do i set the storyboard to user selected language in real time ?

我正在使用Localize-Swift库(链接)来本地化我的应用程序,它可以很好地处理 .strings 文件。问题是我必须本地化为从右到左的语言,我必须通过 Interface Builder Storyboard 本地化,这样我才能使视图控制器在 RTL 格式中看起来正确。问题是如何将故事板实时设置为用户选择的语言?

for example i have 2 storyboard files :

例如,我有 2 个故事板文件:

1- ... /ProjectName/Base.lproj/Main.storyboard

1- ... /ProjectName/Base.lproj/Main.storyboard

2- ... /ProjectName/fa-IR.lproj/Main.storyboard

2- ... /ProjectName/fa-IR.lproj/Main.storyboard

how do i switch between them in real time ?

我如何在它们之间实时切换?

i already know i can change it in Schemes and device language but i want to do it real time and i dont want the users to restart their device.

我已经知道我可以在 Schemes 和设备语言中更改它,但我想实时进行,我不希望用户重新启动他们的设备。

thanks

谢谢

回答by KababChi

found my answer :

找到了我的答案:

NSUserDefaults.standardUserDefaults().setObject(["language identifier"], forKey: "AppleLanguages") 
NSUserDefaults.standardUserDefaults().synchronize()

unfortunately user must restart the app! if anyone could find a solution to not restart the application please inform me.

不幸的是,用户必须重新启动应用程序!如果有人能找到不重新启动应用程序的解决方案,请通知我。

回答by jordivilagut

I think KababChi's answer was right. However, in the newer versions of Swift NSUserDefaultshas been substituted by UserDefaults. So the code would look like this:

我认为 KababChi 的回答是正确的。但是,在较新版本的 Swift 中NSUserDefaults已被UserDefaults. 所以代码看起来像这样:

UserDefaults.standard.set(languages[indexPath.row], forKey: "AppleLanguages")
UserDefaults.standard.synchronize()

App still needs to be restarted to apply these changes.

应用仍需要重新启动才能应用这些更改。

回答by Azamat Bekkhozha

In order to change the language without restarting your device you need to switch ‘lproj' bundle.

为了在不重启设备的情况下更改语言,您需要切换“lproj”包。

You can make it using this code:

您可以使用以下代码进行制作:

class L012Localizer: NSObject {
    class func DoTheSwizzling() {
        MethodSwizzleGivenClassName(cls: Bundle.self, originalSelector: #selector(Bundle.localizedString(forKey:value:table:)), overrideSelector:
            #selector(Bundle.specialLocalizedString(key:value:table:)))
    }
}

extension Bundle {
    @objc func specialLocalizedString(key: String, value: String?, table tableName: String?) -> String {
        let currentLanguage = Localization.currentAppleLanguage()
        var bundle = Bundle();
        if let _path = Bundle.main.path(forResource: currentLanguage, ofType: "lproj") {
            bundle = Bundle(path: _path)!
        } else {
            let _path = Bundle.main.path(forResource: "Base", ofType: "lproj")!
            bundle = Bundle(path: _path)!
        }
        return (bundle.specialLocalizedString(key: key, value: value, table: tableName))
    }
}

func MethodSwizzleGivenClassName(cls: AnyClass, originalSelector: Selector, overrideSelector: Selector){

    let origMethod: Method = class_getInstanceMethod(cls, originalSelector)!;
    let overrideMethod: Method = class_getInstanceMethod(cls, overrideSelector)!;
    if (class_addMethod(cls, originalSelector, method_getImplementation(overrideMethod), method_getTypeEncoding(overrideMethod))) {
        class_replaceMethod(cls, overrideSelector, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
    } else {
        method_exchangeImplementations(origMethod, overrideMethod);
    }
}

Here we are exchanging the implementation of Bundle's localizedString method. Note: we exchanging the Implementation not the reference on the function.

这里我们交换的是 Bundle 的 localizedString 方法的实现。注意:我们交换的是实现而不是函数的参考。

Now add this line in the Appdelegate in the didFinishLaunchingWithOptions delegate method.

现在在 didFinishLaunchingWithOptions 委托方法的 Appdelegate 中添加这一行。

L102Localizer.DoTheSwizzling()

After that you need to reload your ViewControllers. In your Main.storyboard set Root View Controller's StoryboardId to "rootnav" and paste this code to your method that switches language:

之后,您需要重新加载您的 ViewController。在您的 Main.storyboard 中,将根视图控制器的 StoryboardId 设置为“rootnav”并将此代码粘贴到您的切换语言的方法中:

let rootviewcontroller: UIWindow = ((UIApplication.shared.delegate?.window)!)!
rootviewcontroller.rootViewController = self.storyboard?.instantiateViewController(withIdentifier: "rootNav")
let mainwindow = (UIApplication.shared.delegate?.window!)!
mainwindow.backgroundColor = UIColor(hue: 0.6477, saturation: 0.6314, brightness: 0.6077, alpha: 0.8)
UIView.transition(with: mainwindow, duration: 0.55001, options: .transitionFlipFromLeft, animations: { () -> Void in
}) { (finished) -> Void in
}

回答by Keyur Hirani

You can use NSBundle+Languagethird party class.

您可以使用NSBundle+Language第三方类。

回答by David Seek

Maybe the RSMultiLanguage podis something useful for you? I have used it in my apps and it provides to possibility to change the user language in app. I'm pretty sure you can set it depending on the user location with an if loop. That way you might not have to restart the app.

也许RSMultiLanguage pod对您有用?我在我的应用程序中使用了它,它提供了在应用程序中更改用户语言的可能性。我很确定您可以使用 if 循环根据用户位置进行设置。这样您可能不必重新启动应用程序。

RSMultiLanguage

RS多语言

Usage

用法

To run the example project, clone the repo, and run pod install from the Example directory first.

要运行示例项目,请先克隆 repo,然后从 Example 目录运行 pod install。

Installation

安装

RSMultiLanguage is available through CocoaPods. To install it, simply add the following line to your Podfile:

RSMultiLanguage 可通过 CocoaPods 获得。要安装它,只需将以下行添加到您的 Podfile 中:

pod "RSMultiLanguage"

Author

作者

Roy Ng, [email protected]

Roy Ng, [email protected]

License

执照

RSMultiLanguage is available under the MIT license. See the LICENSE file for more info.

RSMultiLanguage 在 MIT 许可下可用。有关详细信息,请参阅许可证文件。

回答by iDevAmit

  1. Requires restart of app. Follow below lines of code.

    UserDefaults.standard.set(["language identifier"], forKey: "AppleLanguages") UserDefaults.standard.synchronize()

  2. Restart of app not requires ( the answer may requires customization in provided source code). Follow the provided web link.

  1. 需要重启应用。遵循以下代码行。

    UserDefaults.standard.set(["language identifier"], forKey: "AppleLanguages") UserDefaults.standard.synchronize()

  2. 不需要重新启动应用程序(答案可能需要在提供的源代码中进行自定义)。按照提供的 Web 链接进行操作。

http://www.factorialcomplexity.com/blog/2015/01/28/how-to-change-localization-internally-in-your-ios-application.html

http://www.factorialcomplexity.com/blog/2015/01/28/how-to-change-localization-internally-in-your-ios-application.html