Swift之本地国际化与App内切换语言

添加语言库
  • 点击项目 -> PROJECT -> Info -> Localizations -> + , 添加需要的语言;

在这里插入图片描述

  • 添加完成的语言库如下所示:

在这里插入图片描述

  • 创建Localizable.strings

在这里插入图片描述

  • 然后选择新创建的 Localizable.string, 选中所需要的语言;

在这里插入图片描述

Localizable.strings 文件写入
  • 添加语言库成功之后, Localizable.strings就生成了English、Chinese Simplified、Chinese Traditional三个语言文件;
  • Localizable.strings 文件中写入, 以"key" = “value”; 这样的格式;
  • English:
INTERNATIONALIZATION = "Internationalization";
CHANGE = "switch";
HANDSOME = "Handsome Boy";
  • Chinese Simplified
INTERNATIONALIZATION = "国际化";
CHANGE = "切换";
HANDSOME = "帅哥";
  • Chinese Traditional
INTERNATIONALIZATION = "國際化";
CHANGE = "切換";
HANDSOME = "帥哥";
YDWLocalizationHelper

该工具类可以直接拖入工程中使用, 主要实现功能:

  • 第一次进入App时, 自动根据系统的语言设定当前App的语言;
  • 保存当前用户设定的语言;
  • 自定义切换语言功能;
  • 控件赋值的获取和设定;
  • 切换语言后替换掉mainBundle为当前语言的bundle;
import UIKit

class YDWLocalizationHelper: NSObject {

    fileprivate static let kSharedSettingsKey = "DefaultUserSettings"
    
    var language: Language
    
    enum Language: String {
        case Chinese = "zh-Hans"
        case English = "en"
        case Tradition = "zh-Hant"
        case Vietnamese = "vi"
        
        var code: String {
            return rawValue
        }
    }

    // MARK: 创建单例
    static let shared: YDWLocalizationHelper = {
        let appSettings: YDWLocalizationHelper
        if let savedData = UserDefaults.standard.object(forKey: YDWLocalizationHelper.kSharedSettingsKey) as? Data,
            let defaultSettings = NSKeyedUnarchiver.unarchiveObject(with: savedData) as? YDWLocalizationHelper {
            appSettings = defaultSettings
        } else {
            appSettings = YDWLocalizationHelper()
        }
        return appSettings
    }()
    
    // MARK: 获取键值
    func valueWithKey(key: String!) -> String {
        let str = NSLocalizedString(key, comment: "")
        return str
    }

    // MARK: - 保存用户当前语言
    static func saveSharedInstance() {
        let data = NSKeyedArchiver.archivedData(withRootObject: YDWLocalizationHelper.shared)
        UserDefaults.standard.set(data, forKey: YDWLocalizationHelper.kSharedSettingsKey)
    }

    static func localeIsChinese() -> Language {
        if let lang = Locale.preferredLanguages.first {
            if lang.hasPrefix("zh") {
                if lang.contains("Hant") || lang.contains("Trad") {
                    return .Tradition
                }
                return .Chinese
            } else if lang.contains("en") {
                return .English
            } else if lang.hasPrefix("viet") {
                return .Vietnamese
            } else {
                return .English
            }
        } else {
            return .English
        }
    }

    // MARK: 首次进入语言
    override init() {
        language = YDWLocalizationHelper.localeIsChinese()
        super.init()
    }

}

private var bundleByLanguageCode: [String: Foundation.Bundle] = [:]

extension YDWLocalizationHelper.Language {
    var bundle: Foundation.Bundle? {
        if let bundle = bundleByLanguageCode[code] {
            return bundle
        } else {
            let mainBundle = Foundation.Bundle.main
            if let path = mainBundle.path(forResource: code, ofType: "lproj"),
                let bundle = Foundation.Bundle(path: path) {
                bundleByLanguageCode[code] = bundle
                return bundle
            } else {
                return nil
            }
        }
    }
}

// 当调用YDWLocalizationHelper.Language切换语言后替换掉mainBundle为当前语言的bundle
class Bundle: Foundation.Bundle {
    override func localizedString(forKey key: String, value: String?, table tableName: String?) -> String {
        if let bundle = YDWLocalizationHelper.shared.language.bundle {
            return bundle.localizedString(forKey: key, value: value, table: tableName)
        } else {
            return super.localizedString(forKey: key, value: value, table: tableName)
        }
    }
}
语言切换
  • AppDelegate中: object_setClass(Foundation.Bundle.main, Bundle.self)
	func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        object_setClass(Foundation.Bundle.main, Bundle.self)
        return true
	}
  • 使用:设定时只需要在控件上, 通过YDWLocalizationHelper.shared.valueWithKey(key: “INTERNATIONALIZATION”)来设定即可; 而切换语言只需要通过设定YDWLocalizationHelper.shared.language = .Chinese即可;(其中valueWithKey和YDWLocalizationHelper.shared.language实现如下)
	// comment 是传参, 假如value中需要外界来决定内容,可以用%@,然后comment传参
	func valueWithKey(key: String!) -> String {
        let str = NSLocalizedString(key, comment: "")
        return str
    }

	// 切换语言时,只要设置就可以:
	YDWLocalizationHelper.shared.language = .Chinese //  .Chinese 
  • 最后重载RootViewController即可:
	let appDelegate = UIApplication.shared.delegate as! AppDelegate
    appDelegate.setupRootViewController()
  • 对于story 中的国际化, 需要重设一下RootViewController
    func resetRootViewController() {
        if let appdelegate = UIApplication.shared.delegate {
            let storyBoard = UIStoryboard.init(name: "Main", bundle: nil)
            if let mainController = storyBoard.instantiateViewController(withIdentifier: "rootViewController") as? UINavigationController {
                appdelegate.window??.rootViewController = mainController
            }
        }
    }
刷新界面

对于所有界面的刷新最方便的就是重新设置 rootViewController, 将keyWindow先变黑,假装loading个几秒,再变回来即可。如果需要再次回到之前所在页面,再添加相应的跳转VC的方法;

	func chooseLanguage(menu: [String : Any]) {
		let language = menu["language"] as! String
        var noticeContent = "正在设置语言..."
        if language == "中文(简体)" {
            noticeContent = "正在设置语言..."
            YDWLocalizationHelper.shared.language = .Chinese
        } else if language == "中文(繁體)" {
            noticeContent = "正在設置語言..."
            YDWLocalizationHelper.shared.language = .Tradition
        } else if language == "English" {
            noticeContent = "Setting Language..."
            YDWLocalizationHelper.shared.language = .English
        } else if language == "Tiếng Việt" {
            noticeContent = "Thiết lập ngôn ngữ..."
            YDWLocalizationHelper.shared.language = .Vietnamese
        } else {
            noticeContent = "正在设置语言..."
            YDWLocalizationHelper.shared.language = .Chinese
        }
        if UIApplication.shared.delegate != nil {
            let appDelegate = UIApplication.shared.delegate as! AppDelegate
            appDelegate.setupRootViewController()
        }
        let backView = UIView(frame: UIScreen.main.bounds)
        backView.backgroundColor = .black
        UIApplication.shared.keyWindow?.addSubview(backView)
        YDWToast.showToast(text: noticeContent, duration: 2, location: .center)
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2) {
            UIView.animate(withDuration: 0.2, animations: {
                backView.alpha = 0
            }) { (isFinished) in
                backView.removeFromSuperview()
            }
        }
	}
效果展示

在这里插入图片描述

完整示例

Swift之Internationalization本地国际化和App内切换语言

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Swift是一种流行的编程语言,广泛用于iOS应用程序的开发。为了满足全球用户的需求,国际化处理变得非常重要。在iOS应用程序中,国际化处理包括支持多种语言和本地化相关的设置。 Swift国际化处理通常涉及本地化字符串、文本、格式、日期、货币等。开发人员需要将文本信息存储在本地化资源文件中,以便根据不同的语言和地区进行自动切换和调用。在Swift中,国际化资源的文件类型为.strings,这些文件存储了一组键值对,其中键表示需要国际化的字符串,值表示本地化后的字符串。当应用程序启动时,Swift会按照用户设备设置来选择对应的本地化资源文件,实现应用程序内文本的自动切换和展示。通过这种方式,开发人员可以支持多种语言国际化特性,为全球用户提供更好的应用程序体验。 针对这一需求,我们开发了一个开源资源库,名为“Internationalization-in-Swift”。该库提供了一组常见的本地化字符串和文本替换处理方式,并实现了本地化资源文件的动态调用和自动化切换。此外,我们还开发了一个名为“AppLocalizationSwitch.zip”的框架,支持在应用程序内动态切换和调用不同的本地化资源文件。使用该框架,开发人员可以快速而可靠地开发多语言应用程序,并实现更好的国际化特性。 总之,Swift国际化处理对于提供高品质的可全球化应用程序体验至关重要。我们推荐开发人员使用开源库“Internationalization-in-Swift”和框架“AppLocalizationSwitch.zip”,以便更好地实现语言和本地化支持。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

╰つ栺尖篴夢ゞ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值