David Sanford David Sanford - 3 months ago 10
Swift Question

Switching the language directly in the application

Have been trying to localize my app into 7 languages, but all tutorials that I found only display how to on a single page, not through out the app.

I am now at the point where the localization works when device is of that language, but need to have ability to change languages via button.

EDIT: The below code works fine for anyone looking for a similar solution

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 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!


override func viewDidLoad()
{
super.viewDidLoad()

configureView()
print(appLanguage)

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



}

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()
[self.viewDidLoad()]
}

func changeToDE(sender: UIButton)
{
appLanguage = "de"
NSUserDefaults.standardUserDefaults().synchronize()
[self.viewDidLoad()]
}

func changeToFR(sender: UIButton)
{
checkmarkShowFR()
appLanguage = "fr"
NSUserDefaults.standardUserDefaults().synchronize()
[self.viewDidLoad()]
}

func changeToES(sender: UIButton)
{
checkmarkShowES()
appLanguage = "es"
NSUserDefaults.standardUserDefaults().synchronize()
[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)
}


}


All text needing to be localized, need to have the suffix .localized, along with the following inside StringExtension.swift

extension String {

var localized: 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
}
}

Answer

Try this sample:

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

Result:

enter image description here