Как заполнить вид сборщика словарем? - PullRequest
1 голос
/ 02 июля 2019

Я хочу заполнить сборщик словарем и у меня возникли проблемы с названием строки.

В основном мой сборщик должен состоять из 2 компонентов и иметь следующий вид:

|Alabama| ---> ["35010", "35011","35012"]
|Arizona| ---> ["99501", "99502"]
|California|--> ["90001", "90002", "90003"]

Первый сборщикдолжен иметь состояния и в зависимости от состояния второй сборщик должен иметь разные значения.Я установил число компонентов как два, так как создал словарь с состоянием в качестве ключей и кодов в качестве значений компонентов, но я не могу заполнить значения в средстве выбора.

 class dependentPicker: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {



     @IBOutlet weak var dependentPicker: UIPickerView!

        let stateToPostalCodeDB = [
            "Alabama" :[ "35010","35011","35012"]
            "Arizona" : [ "85001", "85002"],
            "California": [ "90001","90002","90003"]]

    func numberOfComponents(in pickerView: UIPickerView) -> Int {
            return 2
        }
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
            //
            }
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {

            //

        }

Я могу сделатьРешение с двумя сборщиками, но я хочу знать, как сделать то же самое с 2 компонентами и словарями.Я в основном хочу узнать, как заполнить сборщик словарями.

Ответы [ 2 ]

1 голос
/ 02 июля 2019

Вам лучше создать структуру для хранения состояний и их почтовых индексов.Словарь запутается очень быстро.Во всяком случае, вот код.Смотрите комментарий в пределах.

class ViewController: UIViewController {
    @IBOutlet weak var pickerView: UIPickerView!
    var stateToPostalCodeDB = [
        "Alabama": ["35010", "35011","35012"],
        "Arizona": ["99501", "99502"],
        "California": ["90001", "90002", "90003"]
    ]

    /// The keys in a dictionary are unordered
    /// Create a computed property that sorts the states alphabetically
    var states: [String] { return stateToPostalCodeDB.keys.sorted() }

    override func viewDidLoad() {
        super.viewDidLoad()
        pickerView.dataSource = self
        pickerView.delegate = self
    }
}

/// An enum to define the columns of the UIPickerView
/// Better than using 0 or 1 or any mysterious number
private enum PickerViewComponents: Int, CaseIterable {
    case state, zipCode
}

/// The data source and delegate of the Picker View
extension ViewController: UIPickerViewDataSource, UIPickerViewDelegate {
    /// The number of columns of the Picker View
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return PickerViewComponents.allCases.count
    }

    /// The number of rows for each columns
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        let componentName = PickerViewComponents.allCases[component]
        switch componentName {
        case .state:
            return states.count
        case .zipCode:
            let index = pickerView.selectedRow(inComponent: PickerViewComponents.state.rawValue)
            let state = states[index]
            return stateToPostalCodeDB[state]!.count
        }
    }

    /// The label for each row
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        let componentName = PickerViewComponents.allCases[component]
        switch componentName {
        case .state:
            return states[row]
        case .zipCode:
            let index = pickerView.selectedRow(inComponent: PickerViewComponents.state.rawValue)
            let state = states[index]
            return stateToPostalCodeDB[state]?[row]
        }
    }

    /// If the user changes the state, reload the zip codes
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        let componentName = PickerViewComponents.allCases[component]
        if componentName == .state {
            let zipCode = PickerViewComponents.zipCode.rawValue
            pickerView.reloadComponent(zipCode)
            pickerView.selectRow(0, inComponent: zipCode, animated: true)
        }
    }
}
0 голосов
/ 03 июля 2019

Этот ответ очень похож на отличный ответ CodeDifferent, но с двумя основными отличиями:

  1. Массив State структур заменяет словарь.
  2. Жестко закодированные значения заменяют перечисление PickerViewComponents. Я думаю, что перечисление добавляет ненужную многословность и сложность.

Вот класс контроллера основного вида:

class ViewController: UIViewController {
    @IBOutlet weak var pickerView: UIPickerView!

    let states = [
        State(name: "Alabama", postalCodes: ["35010", "35011","35012"]),
        State(name: "Arizona", postalCodes: ["99501", "99502"]),
        State(name: "California", postalCodes: ["90001", "90002", "90003"])
    ]

    override func viewDidLoad() {
        pickerView.dataSource = self
        pickerView.delegate = self
    }
}

Источник данных и делегат:

extension ViewController: UIPickerViewDataSource, UIPickerViewDelegate {
    /// Number of columns
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 2
    }

    /// Number of rows per column
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        if component == Component.state {
            return states.count
        } else {
            let index = pickerView.selectedRow(inComponent: Component.state)
            return states[index].count
        }
    }

    /// Title for row/column
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        if component == Component.state {
            return states[row]
        } else {
            let index = pickerView.selectedRow(inComponent: Component.state)
            return states[index].postalCodes[row]
        }
    }

    /// Update zip codes if state changes
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        if component == Component.state {
            pickerView.reloadComponent(Component.postalCode)
            pickerView.selectRow(0, inComponent: Component.postalCode, animated: true)
        }
    }
}

Структура:

struct State {
    var name: String
    var postalCodes: [String]
}

struct Component {
    static let state = 0
    static let postalCode = 1
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...