ios - 直接在应用程序中切换语言

标签 ios swift localization

一直在尝试将我的应用程序本地化为 7 种语言,但我发现的所有教程都只在一个页面上展示如何操作,而不是整个应用程序。

我现在正处于当设备使用该语言时本地化工作的地步,但需要能够通过按钮更改语言。

编辑:下面的代码适用于寻找类似解决方案的任何人。

注意事项如下:

  1. 以下代码组创建应用内语言更改,包括标签栏名称。
  2. 您必须将所有数据放在 localize.strings 中,因为 main.strings 将无法使用它。这意味着您需要以编程方式添加所有“返回”、“取消”和导航标题以及菜单项。
  3. 每个“changeToXX”函数中的 NSNotificationCenter 设置为通知 tabBarViewController(或您需要的任何 Controller )语言已更改。

import UIKit 
let AppLanguageKey = "AppLanguage"

let AppLanguageDefaultValue = ""

var appLanguage: String {

get {
    if let language = NSUserDefaults.standardUserDefaults().stringForKey(AppLanguageKey) {
        return language
    } else {
        NSUserDefaults.standardUserDefaults().setValue(AppLanguageDefaultValue, forKey: AppLanguageKey)
        return AppLanguageDefaultValue
    }
}

 set(value) {
     NSUserDefaults.standardUserDefaults().setValue((value), forKey: AppLanguageKey)
 } 

 }

 let languageChangedKey = "languageChanged"

 class SettingsLanguageVC: UIViewController
 {


    @IBOutlet weak var languageENButton: UIButton!
    @IBOutlet weak var flagENImageView: UIImageView!
    @IBOutlet weak var languageENTitleLabel: UILabel!
    @IBOutlet weak var checkmarkEN: UIImageView!

    @IBOutlet weak var languageDEButton: UIButton!
    @IBOutlet weak var flagDEImageView: UIImageView!
    @IBOutlet weak var languageDETitleLabel: UILabel!
    @IBOutlet weak var checkmarkDE: UIImageView!

    @IBOutlet weak var languageFRButton: UIButton!
    @IBOutlet weak var flagFRImageView: UIImageView!
    @IBOutlet weak var languageFRTitleLabel: UILabel!
    @IBOutlet weak var checkmarkFR: UIImageView!

    @IBOutlet weak var languageESButton: UIButton!
    @IBOutlet weak var flagESImageView: UIImageView!
    @IBOutlet weak var languageESTitleLabel: UILabel!
    @IBOutlet weak var checkmarkES: UIImageView!

    var tabBar = TabBarController()
    var MyDelegateClass = ""


    override func viewDidLoad()
    {
        super.viewDidLoad()

        configureView()
        print(appLanguage)

        navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Back".localized, style: .Plain, target: self, action: #selector(SettingsLanguageVC.back(_:)))
        navigationItem.title = "Select a language".localized

    }

    override func didReceiveMemoryWarning()
    {
        super.didReceiveMemoryWarning()
    }


    func setTranslatedText(){
        if appLanguage == "es" {
            checkmarkShowES()

        } else if appLanguage == "de" {
            checkmarkShowDE()

        } else if appLanguage == "fr" {
            checkmarkShowFR()

        } else {
            checkmarkShowEN()
        }

    }
    func configureView(){


        let localeEN = NSLocale(localeIdentifier: "en")
        let English = localeEN.displayNameForKey(NSLocaleIdentifier, value: "en")

        languageENTitleLabel.text = English
        flagENImageView.image = UIImage(named: "flag-en.png")
        languageENButton.addTarget(self, action: #selector(self.changeToEN), forControlEvents: .TouchUpInside)

        //German

        let localeDE = NSLocale(localeIdentifier: "de")
        let German = localeDE.displayNameForKey(NSLocaleIdentifier, value: "de")

        languageDETitleLabel.text = German
        flagDEImageView.image = UIImage(named: "flag-de.png")
        languageDEButton.addTarget(self, action: #selector(self.changeToDE), forControlEvents: .TouchUpInside)

        //French

        let localeFR = NSLocale(localeIdentifier: "fr")
        let French = localeFR.displayNameForKey(NSLocaleIdentifier, value: "fr")

        languageFRTitleLabel.text = French
        flagFRImageView.image = UIImage(named: "flag-fr.png")
        languageFRButton.addTarget(self, action: #selector(self.changeToFR), forControlEvents: .TouchUpInside)

        //Spanish

        let localeES = NSLocale(localeIdentifier: "es")
        let Spanish = localeES.displayNameForKey(NSLocaleIdentifier, value: "es")

        languageESTitleLabel.text = Spanish
        flagESImageView.image = UIImage(named: "flag-es.png")
        languageESButton.addTarget(self, action: #selector(self.changeToES), forControlEvents: .TouchUpInside)


        if appLanguage == "es" {
            checkmarkShowES()

        } else if appLanguage == "de" {
            checkmarkShowDE()

        } else if appLanguage == "fr" {
            checkmarkShowFR()

        } else {
            checkmarkShowEN()
        }
    }


    func changeToEN(sender: UIButton)
    {
        checkmarkShowEN()
        appLanguage = "en"
        NSUserDefaults.standardUserDefaults().synchronize()
        NSNotificationCenter.defaultCenter().postNotificationName(languageChangedKey, object: self)
        [self.viewDidLoad()]
    }

    func changeToDE(sender: UIButton)
    {
        appLanguage = "de"
        NSUserDefaults.standardUserDefaults().synchronize()
        NSNotificationCenter.defaultCenter().postNotificationName(languageChangedKey, object: self)
        [self.viewDidLoad()]
    }

    func changeToFR(sender: UIButton)
    {
        checkmarkShowFR()
        appLanguage = "fr"
        NSUserDefaults.standardUserDefaults().synchronize()
        NSNotificationCenter.defaultCenter().postNotificationName(languageChangedKey, object: self)
        [self.viewDidLoad()]
    }

    func changeToES(sender: UIButton)
    {
        checkmarkShowES()
        appLanguage = "es"
        NSUserDefaults.standardUserDefaults().synchronize()
        NSNotificationCenter.defaultCenter().postNotificationName(languageChangedKey, object: self)
        [self.viewDidLoad()]
    }


    func checkmarkShowEN (){
        self.checkmarkEN.hidden = false
        self.checkmarkDE.hidden = true
        self.checkmarkFR.hidden = true
        self.checkmarkES.hidden = true
    }


    func checkmarkShowDE (){
        self.checkmarkEN.hidden = true
        self.checkmarkDE.hidden = false
        self.checkmarkFR.hidden = true
        self.checkmarkES.hidden = true
    }

    func checkmarkShowFR (){
        self.checkmarkEN.hidden = true
        self.checkmarkDE.hidden = true
        self.checkmarkFR.hidden = false
        self.checkmarkES.hidden = true
    }

    func checkmarkShowES () {

        self.checkmarkEN.hidden = true
        self.checkmarkDE.hidden = true
        self.checkmarkFR.hidden = true
        self.checkmarkES.hidden = false
    }



    @IBAction func back (sender: AnyObject) {
        //back one VC
        navigationController?.popViewControllerAnimated(true)
    }


}

所有需要本地化的文本,需要有.localized后缀,以及StringExtension.swift中的以下内容

    extension String {

var localized: String {
    return localized(appLanguage)
}

var localizeStringUsingSystemLang: String {
    return NSLocalizedString(self, comment: "")
}

func localized(lang:String?) -> String {

    if let lang = lang {
        if let path = NSBundle.mainBundle().pathForResource(lang, ofType: "lproj") {
            let bundle = NSBundle(path: path)
            return NSLocalizedString(self, tableName: nil, bundle: bundle!, value: "", comment: "")
        }
    }

return localizeStringUsingSystemLang
}
}
 return localizeStringUsingSystemLang
    }
}

这是 TabBarController 代码:

  1. 注意:“搜索”、“收藏夹”和“更多”选项卡是系统选项卡。我不得不将它们更改为自定义并手动将名称添加到选项卡并添加我自己的图标。否则它们将不会被本地化。

    导入 UIKit

    类 TabBarController: UITabBarController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    
        setTabViewControllerParams(0, tabBarItemTitle: "Species".localized, navigationItemTitle: filterBy)
        setTabViewControllerParams(1, tabBarItemTitle: "Regions".localized, navigationItemTitle: "My Regions".localized)
        setTabViewControllerParams(2, tabBarItemTitle: "Favorites".localized, navigationItemTitle: "Favorites".localized)
        setTabViewControllerParams(3, tabBarItemTitle: "Search".localized, navigationItemTitle: "")
        setTabViewControllerParams(4, tabBarItemTitle: "More".localized, navigationItemTitle: "Reef Life Apps")
    
        NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(TabBarController.languageChangedTrigger), name: languageChangedKey, object: nil)
    
    }
    
    
    func languageChangedTrigger () {
    
        [self.viewDidLoad()]
    }
    
    
    func setTabViewControllerParams(index: Int, tabBarItemTitle: String, navigationItemTitle: String) {
    
        if let tabBarItems = tabBar.items {
            if index < tabBarItems.count {
                tabBarItems[index].title = tabBarItemTitle
            }
        }
    
        if let viewControllers = viewControllers {
            if index < viewControllers.count {
                if let navigationController = viewControllers[index] as? UINavigationController {
                    if navigationController.viewControllers.count > 0 {
                        let viewController = navigationController.viewControllers[0]
                        viewController.navigationItem.title = navigationItemTitle
                    }
                }
            }
        }
    }
    

最后,我将以下内容添加到 AppDelegate 的“didFinishLaunchingWithOptions”,这样当非英语手机启动时,应用程序将以他们的语言启动,而不是默认的英语。

if NSLocale.currentLocale().objectForKey(NSLocaleLanguageCode)! as! String == "es"
{   appLanguage = "es"
}else if NSLocale.currentLocale().objectForKey(NSLocaleLanguageCode)! as! String == "fr" {
    appLanguage = "fr"
}else if NSLocale.currentLocale().objectForKey(NSLocaleLanguageCode)! as! String == "de" {
    appLanguage = "de"
}else  {
    appLanguage = "en"
}

希望这对您有所帮助。

最佳答案

试试这个示例:

ViewController.swift

import UIKit

let AppLanguageKey = "AppLanguage"
let AppLanguageDefaultValue = "en"

var appLanguage: String {

get {
    if let language = NSUserDefaults.standardUserDefaults().stringForKey(AppLanguageKey) {
        return language
    } else {
        NSUserDefaults.standardUserDefaults().setValue(AppLanguageDefaultValue, forKey: AppLanguageKey)
        return AppLanguageDefaultValue
    }
}

set(value) {
    NSUserDefaults.standardUserDefaults().setValue((value), forKey: AppLanguageKey)
}

}

class ViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()

    NSLog("title user lang: \("Title".localizeString)")
    NSLog("title En: \("Title".localizeString("en"))")
    NSLog("title Ru: \("Title".localizeString("ru"))")
    NSLog("title Fr: \("Title".localizeString("fr"))")
    NSLog("title ??: \("Title".localizeString("blabla"))")
    NSLog("title sysem lnag: \("Title".localizeStringUsingSystemLang)")
    // Do any additional setup after loading the view, typically from a nib.

}
}

StringExtension.swift

import Foundation

extension String {

var localizeString: String {
    return localizeString(appLanguage)
}

var localizeStringUsingSystemLang: String {
    return NSLocalizedString(self, comment: "")
}

func localizeString(lang:String?) -> String {

    if let lang = lang {
        if let path = NSBundle.mainBundle().pathForResource(lang, ofType: "lproj") {
            let bundle = NSBundle(path: path)
            return NSLocalizedString(self, tableName: nil, bundle: bundle!, value: "", comment: "")
        }
    }
    return localizeStringUsingSystemLang
}
}

Localizable.strings (Russian)

"Title" = "Привет";

Localizable.strings (English)

"Title" = "Hello";

Localizable.strings (French)

"Title" = "Salut";

enter image description here

结果:

enter image description here

关于ios - 直接在应用程序中切换语言,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39201644/

相关文章:

ios - RubyMotion 找不到模拟器设备 watch 应用

ios - Apple Watch 应用程序 : run an MKDirectionsRequest through the parent iOS app in the background?

swift - Xcode - 为 Swift Closure 添加自定义文档

objective-c - 事件指示器不在 subview 的中心(与父 View 的大小不同)

ios - 修复 : . 中的错误重复符号 _response ...:链接器命令失败,退出代码为 1(使用 -v 查看调用)

ios - 在我的 iOS 应用程序中播放 Spotify 播放列表或专辑音乐

c# - View 中加载的某些资源未本地化,为什么?

java - 芬兰日期本地化错误?

localization - 您如何为 PayPal Standard 进行法语-加拿大本地化?

android - 使用 ng-template 问题的 ListView 内部的 ScrollView