Как я могу изменить локаль программно с Swift

Я делаю приложение для iOS на XCODE 6.3 Swift. И мое приложение будет иметь выбрать функцию языка как изображение ниже

enter image description here

У меня уже есть раскадровка для моего местного языка. Но я не могу узнать, как изменить локализацию программно от приложения кнопкой.

Любой знает, как сделать это

59
задан 5 August 2018 в 01:29

2 ответа

Это расширяется решение John Pang, если необходимо сразу перевести системные Строки (Назад, Отмена, Сделанная...):

private var kBundleKey: UInt8 = 0

class BundleEx: Bundle {

    override func localizedString(forKey key: String, value: String?, table tableName: String?) -> String {
        if let bundle = objc_getAssociatedObject(self, &kBundleKey) {
            return (bundle as! Bundle).localizedString(forKey: key, value: value, table: tableName)
        }
        return super.localizedString(forKey: key, value: value, table: tableName)
    }

}

private var kBundleUIKitKey: UInt8 = 0

class BundleUIKitEx: Bundle {

    override func localizedString(forKey key: String, value: String?, table tableName: String?) -> String {
        if let bundle = objc_getAssociatedObject(self, &kBundleUIKitKey) {
            return (bundle as! Bundle).localizedString(forKey: key, value: value, table: tableName)
        }
        return super.localizedString(forKey: key, value: value, table: tableName)
    }

}

extension Bundle {

    static let once: Void = {
        object_setClass(Bundle.main, type(of: BundleEx()))
        object_setClass(Bundle(identifier:"com.apple.UIKit"), type(of: BundleUIKitEx()))
    }()

    class func setLanguage(_ language: String?) {
        Bundle.once
        let isLanguageRTL = Bundle.isLanguageRTL(language)
        if (isLanguageRTL) {
            UIView.appearance().semanticContentAttribute = .forceRightToLeft
        } else {
            UIView.appearance().semanticContentAttribute = .forceLeftToRight
        }
        UserDefaults.standard.set(isLanguageRTL, forKey: "AppleTextDirection")
        UserDefaults.standard.set(isLanguageRTL, forKey: "NSForceRightToLeftWritingDirection")
        UserDefaults.standard.synchronize()

        let value = (language != nil ? Bundle.init(path: (Bundle.main.path(forResource: language, ofType: "lproj"))!) : nil)
        objc_setAssociatedObject(Bundle.main, &kBundleKey, value, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC);

        if let uiKitBundle = Bundle(identifier: "com.apple.UIKit") {
            var valueUIKit: Bundle? = nil
            if let lang = language,
                let path = uiKitBundle.path(forResource: lang, ofType: "lproj") {
                valueUIKit = Bundle(path: path)
            }
            objc_setAssociatedObject(uiKitBundle, &kBundleUIKitKey, valueUIKit, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        }

    class func isLanguageRTL(_ languageCode: String?) -> Bool {
        return (languageCode != nil && Locale.characterDirection(forLanguage: languageCode!) == .rightToLeft)
    }

}

, Если Вы хотите перевести системные строки, необходимо сделать то же для Пакета UIKit.

0
ответ дан 1 November 2019 в 11:43
class ViewController: UIViewController {

@IBOutlet weak var resetOutlet: MyButton! {
    didSet {
        resetOutlet.setTitle("RESET".localized().uppercased(), for: .normal)
    }
}`
}

extension String {

func localized(tableName: String = "Localizable") -> String {
    if let languageCode = Locale.current.languageCode, let preferredLanguagesFirst = Locale.preferredLanguages.first?.prefix(2)  {
        if languageCode != preferredLanguagesFirst {
            if let path = Bundle.main.path(forResource: "en", ofType: "lproj") {
                let bundle = Bundle.init(path: path)
                return NSLocalizedString(self, tableName: tableName, bundle: bundle!, value: self, comment: "")
            }
        }
        }
    return NSLocalizedString(self, tableName: tableName, value: self, comment: "")
}
}
1
ответ дан 1 November 2019 в 11:43

Другие вопросы по тегам:

Похожие вопросы: