Stuck Beginner
Stuck Beginner

Reputation: 93

UIPIckerViews working together in one UIView

looked at the other similar questions but have not found the answers there. Sorted out some of the issues I had but still have the issue where the data from the first pickerView determines what selections there are in the second pickerView (this part of app is a units convertor).

I understand what is going wrong but cannot see how to fix the problem. Through print statements I can see that when I change the first pickerView, the value which holds the number of rows in the second pickerView changes. But the second pickerView titles do not change so that when I go to an item that is higher than index number in the new array, the app crashes. This is confirmed by the error Index out of range.

I have included code and a snapshot of what the pickerViews look like (no formatting or making it pretty - like to get functionality first).

Thanks for any help.

enter image description here

import UIKit

import Foundation

class ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate {

var conversionTypes = ["length", "mass", "area", "volume", "rate", "temp", "pressure"]
var conversionItems = [["metres", "feet", "yard", "inch", "cm"], ["kg", "lbs", "tonne", "ounces"], ["ft2", "m2", "in2"], ["US Gall", "UK Gall", "Bbls", "ft3", "m3"], ["bbl/min", "scf/min", "scf/hr"], ["degC", "degF", "Kelvin"], ["bar", "psi"]]
var littlePickerType = 0
var wheelOne = 0
var wheelTwo = 0



@IBOutlet weak var numberToConvert: UITextField!
@IBOutlet weak var answerLabel: UILabel!


@IBOutlet weak var littlePicker: UIPickerView!
@IBOutlet weak var bigPicker: UIPickerView!


override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
    littlePicker.delegate = self
    littlePicker.dataSource = self
    bigPicker.delegate = self
    bigPicker.dataSource = self

    let tap = UITapGestureRecognizer(target: self.view, action: #selector(UIView.endEditing))
    view.addGestureRecognizer(tap)
}


func numberOfComponents(in pickerView: UIPickerView) -> Int {
    if pickerView == littlePicker {
        return 1
    } else if pickerView == bigPicker {
        return 2
    }

    return 1
}


func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    if pickerView == littlePicker {
        return conversionTypes.count
    } else if pickerView == bigPicker {
        return conversionItems[littlePickerType].count
    }

    return 1
}

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

    if pickerView == littlePicker {
        return conversionTypes[row]
    } else if pickerView == bigPicker {
        return conversionItems[littlePickerType][row]
    }
    return ""
}

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

    if pickerView == littlePicker {
        littlePickerType = row
    } else if pickerView == bigPicker {
        if component == 0 {
            wheelOne = row
        } else if component == 1 {
            wheelTwo = row
        }
    }

    print ("Conversion Type \(littlePickerType) WheelOne \(wheelOne) WheelTwo \(wheelTwo) count \(conversionItems[littlePickerType].count)")


}

}

Upvotes: 1

Views: 46

Answers (1)

Sweeper
Sweeper

Reputation: 271410

You should be calling reloadAllComponents on your big picker whenever littlePickerType changes. This causes all the picker view data source methods (especially titleForRow) to be called again for the big picker.

var littlePickerType = 0 {
    didSet {
        bigPicker.reloadAllComponents()
    }
}

Upvotes: 1

Related Questions