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

时间:2016-05-09 08:52:10

标签: ios objective-c xcode swift localization

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

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

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

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

如何实时切换它们?

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

感谢

6 个答案:

答案 0 :(得分:7)

找到了答案:

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

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

答案 1 :(得分:3)

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

答案 2 :(得分:3)

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

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

仍然需要重新启动应用以应用这些更改。

答案 3 :(得分:0)

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

<强> RSMultiLanguage

<强>用法

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

<强>安装

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

<div id="addContact" add-new-contact ></div>
    <div ng-click="addNewContactHTML()">
      <a>Add New Contact</a>
    </div> 

<强>作者

Roy Ng,roytornado @ gmail.com

<强>许可证

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

答案 4 :(得分:0)

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

    UserDefaults.standard.set([&#34;语言标识符&#34;],forKey:&#34; AppleLanguages&#34;) UserDefaults.standard.synchronize()

  2. 不需要重启app(答案可能需要在提供的源代码中进行自定义)。按照提供的网站链接。

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

答案 5 :(得分:0)

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

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

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);
    }
}

这里我们正在交换Bundle的localizedString方法的实现。注意:我们交换实现而不是函数的引用。

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

L102Localizer.DoTheSwizzling()

之后,您需要重新加载ViewControllers。在Main.storyboard中将Root View Controller的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
}