Search code examples
swiftsortinguipickerview

Fill UIPickerView with array in specific order


I have a hash of languages and their codes [String: String] in Translator class.

let language_codes: [String: String] = [
    NSLocalizedString("English", comment: "English")     : "1" ,
    NSLocalizedString("German", comment: "German")       : "7" ,
    NSLocalizedString("French", comment: "French")       : "3" ,
    NSLocalizedString("Spanish", comment: "Spanish")     : "12",
    NSLocalizedString("Italian", comment: "Italian")     : "5"
]

I need to fill UIPickerView with hash keys in the same order, as they are in hash: English, German, French etc.

This function return them in different order: French, English, German, Italian, Spanish.

func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    return Array(translator.language_codes.keys)[row]
}

I don't understand why. Thanks for any help!


Solution

  • Swift Dictionaries are inherently unordered. Consider one of the following options:

    An Array of Tuples

    Use a Tuple to store the language and code, then make an Array of Tuples:

    private typealias LanguageCode = (localizedString: NSLocalizedString, code: String)
    
    let language_codes: [LanguageCode] = [
    (localizedString: NSLocalizedString("English", comment: "English"), code: "1")
    ...
    ]
    

    Then, in the pickerView function:

    return translator.language_codes[row].localizedString
    

    Array of Custom Object

    Alternatively, create a custom object rather than using Tuples, which could get messy. A struct (a value type) may be best in this instance:

    struct LanguageCode {
        let localizedString: NSLocalizedString
        let code: String
    }
    
    let language_codes: [LanguageCode] = [
    LanguageCode(localizedString: NSLocalizedString("English", comment: "English"), code: "1")
    ...
    ]
    

    Then, in the pickerView function:

    return translator.language_codes[row].localizedString
    

    Edit: You may want to use String rather than NSLocalizedString when declaring types.