J'ai déjà vu deux questions similaires aux miennes, mais les réponses à ces questions ne fonctionnent pas pour moi. J'ai un ancien projet avec une liste de pays tapés manuellement dans un ensemble de crochets.
Je peux facilement l'utiliser dans mon pickerView, mais je me demande s'il existe un moyen plus efficace de le faire?
J'utiliserai la liste des pays dans un UIPickerView.
Vous pouvez obtenir une liste de pays en utilisant isoCountryCodes
de la classe NSLocale qui retourne un tableau de [String]
. De là, vous obtenez le nom du pays en utilisant la méthode displayName(forKey:)
de NSLocale
. Cela ressemble à ceci:
var countries: [String] = []
for code in NSLocale.isoCountryCodes {
let id = NSLocale.localeIdentifier(fromComponents: [NSLocale.Key.countryCode.rawValue: code])
let name = NSLocale(localeIdentifier: "en_UK").displayName(forKey: NSLocale.Key.identifier, value: id) ?? "Country not found for code: \(code)"
countries.append(name)
}
print(countries)
Swift 3 et 4
var countries: [String] = []
for code in NSLocale.isoCountryCodes as [String] {
let id = NSLocale.localeIdentifier(fromComponents: [NSLocale.Key.countryCode.rawValue: code])
let name = NSLocale(localeIdentifier: "en_UK").displayName(forKey: NSLocale.Key.identifier, value: id) ?? "Country not found for code: \(code)"
countries.append(name)
}
print(countries)
Identique à Ian mais plus court
let countries = NSLocale.ISOCountryCodes().map { (code:String) -> String in
let id = NSLocale.localeIdentifierFromComponents([NSLocaleCountryCode: code])
return NSLocale(localeIdentifier: "en_US").displayNameForKey(NSLocaleIdentifier, value: id) ?? "Country not found for code: \(code)"
}
print(countries)
Voici la réponse de @ vedo27 en Swift 3
let countries = NSLocale.isoCountryCodes.map { (code:String) -> String in
let id = NSLocale.localeIdentifier(fromComponents: [NSLocale.Key.countryCode.rawValue: code])
return NSLocale(localeIdentifier: "en_US").displayName(forKey: NSLocale.Key.identifier, value: id) ?? "Country not found for code: \(code)"
}
Swift 4.2
let languageList = Locale.isoLanguageCodes.compactMap { Locale.current.localizedString(forLanguageCode: $0) }
let countryList = Locale.isoRegionCodes.compactMap { Locale.current.localizedString(forRegionCode: $0) }
il est également recommandé de localiser le nom affiché des pays. Donc, en plus de la réponse vedo27, ce serait:
let countriesArray = NSLocale.ISOCountryCodes().map { (code:String) -> String in
let id = NSLocale.localeIdentifierFromComponents([NSLocaleCountryCode: code])
let currentLocaleID = NSLocale.currentLocale().localeIdentifier
return NSLocale(localeIdentifier: currentLocaleID).displayNameForKey(NSLocaleIdentifier, value: id) ?? "Country not found for code: \(code)"
}
Swift 4
Voici une manière élégante de le faire dans Swift 4
var countries: [String] = {
var arrayOfCountries: [String] = []
for code in NSLocale.isoCountryCodes as [String] {
let id = NSLocale.localeIdentifier(fromComponents: [NSLocale.Key.countryCode.rawValue: code])
let name = NSLocale(localeIdentifier: "en_UK").displayName(forKey: NSLocale.Key.identifier, value: id) ?? "Country not found for code: \(code)"
arrayOfCountries.append(name)
}
return arrayOfCountries
}()
Swift 3 déclaré comme var
:
var countries: [String] {
let myLanguageId = "en" // in which language I want to show the list
return NSLocale.isoCountryCodes.map {
return NSLocale(localeIdentifier: myLanguageId).localizedString(forCountryCode: $0) ?? $0
}
}
Swift Vous pouvez facilement récupérer le nom des pays et leurs drapeaux emoji.
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var countriesData = [(name: String, flag: String)]()
for code in NSLocale.isoCountryCodes {
let flag = String.emojiFlag(for: code)
let id = NSLocale.localeIdentifier(fromComponents: [NSLocale.Key.countryCode.rawValue: code])
if let name = NSLocale(localeIdentifier: "en_UK").displayName(forKey: NSLocale.Key.identifier, value: id) {
countriesData.append((name: name, flag: flag!))
}else{
//"Country not found for code: \(code)"
}
}
print(countriesData)
}
}
extension String {
static func emojiFlag(for countryCode: String) -> String! {
func isLowercaseASCIIScalar(_ scalar: Unicode.Scalar) -> Bool {
return scalar.value >= 0x61 && scalar.value <= 0x7A
}
func regionalIndicatorSymbol(for scalar: Unicode.Scalar) -> Unicode.Scalar {
precondition(isLowercaseASCIIScalar(scalar))
// 0x1F1E6 marks the start of the Regional Indicator Symbol range and corresponds to 'A'
// 0x61 marks the start of the lowercase ASCII alphabet: 'a'
return Unicode.Scalar(scalar.value + (0x1F1E6 - 0x61))!
}
let lowercasedCode = countryCode.lowercased()
guard lowercasedCode.count == 2 else { return nil }
guard lowercasedCode.unicodeScalars.reduce(true, { accum, scalar in accum && isLowercaseASCIIScalar(scalar) }) else { return nil }
let indicatorSymbols = lowercasedCode.unicodeScalars.map({ regionalIndicatorSymbol(for: $0) })
return String(indicatorSymbols.map({ Character($0) }))
}
}
Résultat :
Alternativement, vous pouvez l'avoir dans Swift 4 et localisé par la langue du système.
import Foundation
struct Country {
let name: String
let code: String
}
final class CountryHelper {
class func allCountries() -> [Country] {
var countries = [Country]()
for code in Locale.isoRegionCodes as [String] {
if let name = Locale.autoupdatingCurrent.localizedString(forRegionCode: code) {
countries.append(Country(name: name, code: code))
}
}
return countries
}
}
Mise à jour de la réponse de vedo27 mais dans Swift 5:
let countries : [String] = NSLocale.isoCountryCodes.map { (code:String) -> String in
let id = NSLocale.localeIdentifier(fromComponents: [NSLocale.Key.countryCode.rawValue: code])
return NSLocale(localeIdentifier: "en_US").displayName(forKey: NSLocale.Key.identifier, value: id) ?? "Country not found for code: \(code)"
}
Aussi pour avoir un tableau trié pour les pays dans l'ordre alphabétique, ajoutez ceci ci-dessous dans votre commande après avoir récupéré la liste des pays
let sortedcountries = countries.sorted { $0 < $1 }