Как изменить язык локализации без перезапуска приложения swift4? - PullRequest
0 голосов
/ 03 июля 2018

Здравствуйте, я пытаюсь изменить файл строки локализации без перезапуска приложения, после изменения языка мне нужно перезапустить приложение, чтобы увидеть новый язык, так я меняю язык приложения, но мне нужно перезапустить приложение, чтобы увидеть изменения, используя эта библиотека https://github.com/marmelroy/Localize-Swift Мне нужно программно установить все значения меток, что является головной болью. Я не хочу, чтобы так было

var selectedLanguage:Languages
let preferredLanguage : String = Bundle.main.preferredLocalizations.first!
print("app langugage \(preferredLanguage)")
if(preferredLanguage == "en") {
    // Localize.setCurrentLanguage("de")
    selectedLanguage = .de
    LanguageManger.shared.setLanguage(language: selectedLanguage)
}
else {
    // Localize.setCurrentLanguage("en")
    selectedLanguage = .en
    LanguageManger.shared.setLanguage(language: selectedLanguage)

}

LanguageManger.shared.setLanguage(language: selectedLanguage)

// return to root view contoller and reload it

let transition: UIViewAnimationOptions = .transitionFlipFromLeft
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: transition, animations: { () -> Void in
        }) { (finished) -> Void in

}

Ответы [ 2 ]

0 голосов
/ 18 марта 2019

В swift 4 я решил это без необходимости перезапуска или использования библиотек. Перепробовав много вариантов, я нашел эту функцию, где вы передаете stringToLocalize (Localizable.String, файл строк), который вы хотите перевести, и язык, на который вы хотите перевести его, и что он возвращает, это значение для та строка, которая у вас есть в файле строк:

    func localizeString (stringToLocalize: String, language: String) -> String
    {
        let path = Bundle.main.path (forResource: language, ofType: "lproj")
        let languageBundle = Bundle (path: path!)
        return languageBundle! .localizedString (forKey: stringToLocalize, value: "", table: nil)
    }

Учитывая эту функцию, я создал ее как глобальную в файле Swift:

struct CustomLanguage {

    func createBundlePath () -> Bundle {
        let selectedLanguage = //recover the language chosen by the user (in my case, from UserDefaults)
        let path = Bundle.main.path(forResource: selectedLanguage, ofType: "lproj")
        return Bundle(path: path!)!
    }
}

Для доступа ко всему приложению и в каждой строке остальных ViewControllers вместо:

NSLocalizedString ("StringToLocalize", comment: “")

Я заменил его на

let customLang = CustomLanguage() //declare at top

NSLocalizedString("StringToLocalize", tableName: nil, bundle: customLang.createBundlePath(), value: "", comment: “”) //use in each String

Я не знаю, является ли это лучшим способом, но я нашел его очень простым, и он работает для меня, надеюсь, он вам поможет!

0 голосов
/ 03 июля 2018

Создайте новый класс NSBundle + Language.h, NSBundle + Language.m. И не забудьте добавить соединительный заголовок.

NSBundle + Language.h

#import <Foundation/Foundation.h>

@interface NSBundle (Language)
+(void)setLanguage:(NSString*)language;
@end

NSBundle + Language.m

#import "NSBundle+Language.h"

#import <objc/runtime.h>

static const char _bundle=0;

@interface BundleEx: NSBundle
@end

@implementation BundleEx
-(NSString*)localizedStringForKey:(NSString *)key value:(NSString *)value table:(NSString *)tableName
{
    NSBundle* bundle=objc_getAssociatedObject(self, &_bundle);
    return bundle ? [bundle localizedStringForKey:key value:value table:tableName]: [super localizedStringForKey:key value:value table:tableName];
}
@end

@implementation NSBundle (Language)

+(void)setLanguage:(NSString*)language
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^
                  {
                      object_setClass([NSBundle mainBundle],[BundleEx class]);
                  });
    objc_setAssociatedObject([NSBundle mainBundle], &_bundle, language ? [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:language ofType:@"lproj"]]: nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end

После этого используйте этот языковой менеджер, чтобы изменить язык: -

class LanguageManager: NSObject {
    //MARK: Set language preference

    class func setSelectedLanguage(dictionary: [String: String]) {
        let userDefaults = UserDefaults.standard
        userDefaults.set(dictionary, forKey: kSelectedLanguageDetails)
        userDefaults.synchronize()
    }

    class  func getSelectedLanguage() ->  [String: String]? {

        let userDefaults = UserDefaults.standard
        return userDefaults.value(forKey: kSelectedLanguageDetails) as?  [String: String]
    }

    class func getSelectedLangaugeCode() -> String{
        if let selectedLanguageDetails = LanguageManager.getSelectedLanguage() {
            if let languageCode =  selectedLanguageDetails[LocalizationKeys.kLanguageCode.rawValue]  {
                Bundle.setLanguage(LanguageManager.getAppleLanguageCode(languageCode: languageCode.lowercased()))
                return languageCode.lowercased()
            }
            else {
                let languageDetails = [LocalizationKeys.kLanguageCode.rawValue:"EN", LocalizationKeys.kLanguageName.rawValue:"English", LocalizationKeys.kLanguageID.rawValue:"1"]
                LanguageManager.setSelectedLanguage(dictionary: languageDetails)
                if let languageCode =  languageDetails[LocalizationKeys.kLanguageCode.rawValue] {
                    Bundle.setLanguage(LanguageManager.getAppleLanguageCode(languageCode: languageCode.lowercased()))
                    return languageCode.lowercased()
                }
            }
        }
        else {
            let languageDetails = [LocalizationKeys.kLanguageCode.rawValue:"EN", LocalizationKeys.kLanguageName.rawValue:"English", LocalizationKeys.kLanguageID.rawValue:"1"]
            LanguageManager.setSelectedLanguage(dictionary: languageDetails )
            if let languageCode =  languageDetails[LocalizationKeys.kLanguageCode.rawValue] {
                Bundle.setLanguage(LanguageManager.getAppleLanguageCode(languageCode: languageCode.lowercased()))
                return languageCode.lowercased()
            }
        }
        return "en"
    }

    /// Checks for the Language preferences selected by user
    class func checkLanguagePreferenceAndSetToDefaults() {
        if let selectedLanguageDetails = LanguageManager.getSelectedLanguage() {
            if let languageCode =  selectedLanguageDetails[LocalizationKeys.kLanguageCode.rawValue]  {
                Bundle.setLanguage(LanguageManager.getAppleLanguageCode(languageCode: languageCode.lowercased()))
            }
            else {
                let languageDetails = [LocalizationKeys.kLanguageCode.rawValue:"EN", LocalizationKeys.kLanguageName.rawValue:"English", LocalizationKeys.kLanguageID.rawValue:"1"]
                LanguageManager.setSelectedLanguage(dictionary: languageDetails)
                if let languageCode =  languageDetails[LocalizationKeys.kLanguageCode.rawValue] {
                    Bundle.setLanguage(LanguageManager.getAppleLanguageCode(languageCode: languageCode.lowercased()))
                }
            }
        }
        else {
            let languageDetails = [LocalizationKeys.kLanguageCode.rawValue:"EN", LocalizationKeys.kLanguageName.rawValue:"English", LocalizationKeys.kLanguageID.rawValue:"1"]
            LanguageManager.setSelectedLanguage(dictionary: languageDetails )
            if let languageCode =  languageDetails[LocalizationKeys.kLanguageCode.rawValue] {
                Bundle.setLanguage(LanguageManager.getAppleLanguageCode(languageCode: languageCode.lowercased()))
            }
        }
    }


    //MARK: Get Language Code

    /// Return apple specific language code
    ///
    /// - parameter languageCode: language code string
    ///
    /// - returns: apples language code
    static func getAppleLanguageCode(languageCode:String) -> String{
        switch languageCode.lowercased() {
        case "en":
            return "en"
        case "es":
            return "es"
        case "fr":
            return "fr"
        case "de":
            return "de"
        case "it":
            return "it"

        default:
            return languageCode
        }
    }
}

Определите языковые параметры следующим образом: -

let KlanguageOptionArray: [[String:String]] = [
    [
        "LanguageCode": "EN",
        "Name": "English",
        "LanguageID": "1"
        ],
    [
        "LanguageCode": "ES",
        "Name": "Español",
        "LanguageID": "2"
        ],
    [
        "LanguageCode": "FR",
        "Name": "Français",
        "LanguageID": "3"
        ],
    [
        "LanguageCode": "DE",
        "Name": "Deutsch",
        "LanguageID": "4"
        ],
    [
        "LanguageCode": "IT",
        "Name": "Italiano",
        "LanguageID": "5"
        ]
]

Изменить выбранный язык с помощью кода ниже

let selectedLanguageDetails = self.languageOptionArray[indexPath.row]
LanguageManager.setSelectedLanguage(dictionary: selectedLanguageDetails)
if let languageCode = selectedLanguageDetails[LocalizationKeys.kLanguageCode.rawValue] {
            Bundle.setLanguage(LanguageManager.getAppleLanguageCode(languageCode: languageCode.lowercased()))
      NotificationCenter.default.post(name: NSNotification.Name(rawValue: NotificationCenterTypes.ReloadTableOnLanguageChangeNotification), object: nil)
   }

И не забывайте добавлять это при каждом запуске

if let selectedLanguageDetails = LanguageManager.getSelectedLanguage() {
    if let languageCode =  selectedLanguageDetails[LocalizationKeys.kLanguageCode.rawValue]  {
        Bundle.setLanguage(LanguageManager.getAppleLanguageCode(languageCode: languageCode.lowercased()))
    }
    else {
    }
}

Надеюсь, это поможет вам

...