简体   繁体   中英

UIPickerView in Swift

I have a label that I want programmatically add a birthdate from my user, I manage to populate with data, but I can't extract data correctly, here is my code: that show an error like the index is out of range, and crash my app

class SignUpFormViewController: UIViewController {

    let date = Date()
    let formatter = DateFormatter()
    let years = (1800...2100).map{String($0)}
    let days = (1...31).map{String($0)}
    var pickerMonth: [String] = [String]()
    var pickerDay: [String] = [String]()
    var pickYears: [String] = [String]()

    var selectedMonth: String?
    var selectedDay: String?
    var selectedYear: String?

//other stuff

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        handleGestureRecognizer()
        self.datePickerView.delegate = self
        self.datePickerView.dataSource = self
        datePickerComponents()
    }

}

extension SignUpFormViewController: UIPickerViewDelegate, UIPickerViewDataSource {

    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 3
    }

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {

        if component == 0 {
            return pickerMonth.count//month
        }else if component == 1 {
            return pickerDay.count//day
        }else {
            return pickYears.count//year
        }
    }

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {

        if component == 0 {
            return pickerMonth[row]
        }else if component == 1 {
            return pickerDay[row]
        }else {
            return pickYears[row]
        }
    }

    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {

        birthDateTextField.text = "\(pickerMonth[row])/\(pickerDay[row])/\(pickYears[row])"
    }

    func datePickerComponents() {
        pickerMonth = formatter.shortMonthSymbols
        pickerDay = days
        pickYears = years
    }

}

The problem is here:

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    birthDateTextField.text = "\(pickerMonth[row])/\(pickerDay[row])/\(pickYears[row])"
}


That's way too simple-minded. Think about it. The user spins only one component at a time, and your method is called. Let's say it's the year component that the user spun. You've got 300 of those. So row could be 300 (let's say). But pickerMonth doesn't have 300 months in it! So you crash when you naively say pickerMonth[row] .

What you want to do is ask the picker view what row is selected in all three components and use that row for that component.

birthDateTextField.text = 
    pickerMonth[pickerView.selectedRow(inComponent:0)]
    + "/" + 
    pickerDay[pickerView.selectedRow(inComponent:1)]
    + "/" + 
    pickYears[pickerView.selectedRow(inComponent:2)]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM