Search code examples
swiftxcodeuipickerview

PickerView ViewForRow Doesn't Recognize Components


I'm using multiple components to make a timer. My pickerView doesn't recognize my second dataSource when I incorporate it with ViewForRow

let hourDataSource = ["0", "1", "2", "3", "4", "5"]
let minDataSource = ["0", "10", "20", "30", "40", "50"]

func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
    let label = UILabel()

    if component == 0 {
        label.text = String(row)
        label.textAlignment = .center
    } else if component == 1 {
        label.text = String(row)
        label.textAlignment = .center
    }
    print(component)
    return label

}

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

    if let label = pickerView.view(forRow: row, forComponent: component) as? UILabel {

        if component == 0, row > 1 {
            label.text = String(row) + " hours"
        } else if component == 0 {
            label.text = String(row) + " hour"
        } else if component == 1 {
            label.text = String(row) + " min"
        }
    }

    //print(component)
    let hour = dataSource[pickerView.selectedRow(inComponent: 0)]
    let min = minDataSource[pickerView.selectedRow(inComponent: 1)]
    timerPickerViewLbl.text = "\(hour):\(min) hrs"
}
 func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {

    if component == 0 {
        return dataSource[row]
    } else {
        return minDataSource[row]
    }
}

I'm printing the components so I know its getting called. When I delete the viewForRow function, my data is correct for the 1st column and 2nd column. But I lose the hour and minute label next to my data. But adding it makes my 2nd column return the same data as my 1st. What's am I missing?


Solution

  • This is all you need. You are only supposed to use one of the delegates, either titleForRow or viewForRow because both of them do the same thing, i.e, give title to the row. Your problem is in the didSelect delegate where you are actually returning the data.

    let hourDataSource = ["0", "1", "2", "3", "4", "5"]
    let minDataSource = ["0", "10", "20", "30", "40", "50"]
    
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        let hour = dataSource[pickerView.selectedRow(inComponent: 0)]
        let min = minDataSource[pickerView.selectedRow(inComponent: 1)]
        timerPickerViewLbl.text = "\(hour):\(min) hrs"
    }
    
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        if component == 0, row > 1 {
            return "\(hourDataSource[row]) hours"
        } else if component == 0 {
            return "\(hourDataSource[row]) hour"
        } else if component == 1 {
            return "\(minDataSource[row]) mins"
        }
        return nil
    }