0

please forgive my ignorance. I am learning from near scratch.

I'm trying to populate multiple pickerView instances based on the selection of a pickerView at the top of the view. I want the choices shown in the remaining pickerviews to depend on what item has been selected in the first pickerview.

I have 6 pickerViews in total. the 1st makes the general selection I want to base the remainder on.

Pickerview1 has 4 components. If the user selects component 4, all remaining pickerViews to show choices. If the user selects component 2 or 3, I want pickerView 4 and 5 to display N/A while the others show choices. If the user selects component 1, I want pickerViews 3-5 to display N/A while 1-2 show choices.

I assume to do this, I would need the index value of the selected component in pickerView1 to make an if else statement for the func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent etc.

I found selectedRow(inComponent:) in the documentation but have not been able to find working examples of how to implement it in my case.

Attached are some snips of my code so far: import UIKit

class FirstViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource { func numberOfComponents(in pickerView: UIPickerView) -> Int { return 1 }

    var capacities = ["6","9","12","15","18","24"]
    var notUsed = "N/A"
    var oduList = ["MXZ-2C20", "MXZ-3C24", "MXZ-3C30", "MXZ-5C42"]
    var result:Float = 0.0
    var one4num:Float = 1.0
    var factor:Float = 1.08
    var per5ft:Float = 5
    var factory:Float = 98

    var selectedRow = 1

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        selectedRow = pickerView.selectedRow(inComponent: index)
        if pickerView == oduPicker {
            return oduList.count
        }
        else if pickerView == idu1PickerView {
            return capacities.count
        }
        else if pickerView == idu2PickerView {
            return capacities.count
        }
        else if pickerView == idu3PickerView {
            return capacities.count
        }
        else if pickerView == idu4PickerView {
            return capacities.count
        }
        else {
            return capacities.count
        }
    }
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        if pickerView == oduPicker {
            return oduList[row]
        }
        else if pickerView == idu1PickerView {
            return capacities[row]
        }
        else if pickerView == idu2PickerView {
            return capacities[row]
        }
        else {
            return capacities[row]
        }
    }
    @IBOutlet weak var oduPicker: UIPickerView!

    @IBOutlet weak var idu1PickerView: UIPickerView!
    @IBOutlet weak var idu2PickerView: UIPickerView!
    @IBOutlet weak var idu3PickerView: UIPickerView!
    @IBOutlet weak var idu4PickerView: UIPickerView!
    @IBOutlet weak var idu5PickerView: UIPickerView!

    @IBOutlet weak var one4Label: UILabel!
    @IBOutlet weak var one4Slider: UISlider!



    @IBOutlet weak var output: UILabel!




    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        self.oduPicker.delegate = self
        self.oduPicker.dataSource = self
        self.idu1PickerView.delegate = self
        self.idu1PickerView.dataSource = self
        self.idu2PickerView.delegate = self
        self.idu2PickerView.dataSource = self
        self.idu3PickerView.delegate = self
        self.idu3PickerView.dataSource = self
    }

    @IBAction func one4Slider(_ sender: Any) {
        one4Label.text = "\(one4Slider.value)"
    }
    @IBAction func three8Slider(_ sender: Any) {
        three8Label.text = "\(three8Slider.value)"


    }
    @IBAction func calculateButton(_ sender: Any) {
        result = factor*(one4num-factory)/per5ft
        output.text = "\(result)"
    }
}

If I implement the suggestion this way:

import UIKit

class FirstViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
    return 1
}

var capacities = ["6","9","12","15","18","24"]
var notUsed = ["N/A"]
var oduList = ["MXZ-2C20", "MXZ-3C24", "MXZ-3C30", "MXZ-5C42"]
var result:Float = 0.0
var one4num:Float = 1.0
var factor:Float = 1.08
var per5ft:Float = 5
var factory:Float = 98

var rowSelected: Int?


func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    if pickerView == oduPicker{
        self.rowSelected = row
        // make anything
    }

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

    if pickerView == oduPicker {
        return oduList.count
    }
    else if pickerView == idu1PickerView {
        return capacities.count
    }
    else if pickerView == idu2PickerView {

        return capacities.count
    }
    else if pickerView == idu3PickerView {
        if rowSelected!  < 2 {
            return 1
        }
        else {
            return capacities.count
        }
    }
    else if pickerView == idu4PickerView {
        if rowSelected! < 3 {
            return 1
        }
        else {
            return capacities.count
        }
    }
    else {
        if rowSelected! < 4 {
            return 1
        }
        else {
            return capacities.count
        }
    }
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    if pickerView == oduPicker {
        return oduList[row]
    }
    else if pickerView == idu1PickerView {
        return capacities[row]
    }
    else if pickerView == idu2PickerView {
        return capacities[row]
    }
    else if pickerView == idu3PickerView {
        if rowSelected! < 2 {
            return notUsed[row]
        }
        else {
            return capacities[row]
        }
    }
    else if pickerView == idu4PickerView {
        if rowSelected! < 3 {
            return notUsed[row]
        }
        else {
            return capacities[row]
        }
    }
    else if pickerView == idu5PickerView {
        if rowSelected! < 4 {
            return notUsed[row]
        }
        else {
            return capacities[row]
        }
    }
    else {
        return capacities[row]
    }
}



@IBOutlet weak var oduPicker: UIPickerView!

@IBOutlet weak var idu1PickerView: UIPickerView!
@IBOutlet weak var idu2PickerView: UIPickerView!
@IBOutlet weak var idu3PickerView: UIPickerView!
@IBOutlet weak var idu4PickerView: UIPickerView!
@IBOutlet weak var idu5PickerView: UIPickerView!

@IBOutlet weak var one4Label: UILabel!
@IBOutlet weak var one4Slider: UISlider!



@IBOutlet weak var output: UILabel!




override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    self.oduPicker.delegate = self
    self.oduPicker.dataSource = self
    self.idu1PickerView.delegate = self
    self.idu1PickerView.dataSource = self
    self.idu2PickerView.delegate = self
    self.idu2PickerView.dataSource = self
    self.idu3PickerView.delegate = self
    self.idu3PickerView.dataSource = self
    self.idu4PickerView.delegate = self
    self.idu4PickerView.dataSource = self
    self.idu5PickerView.delegate = self
    self.idu5PickerView.dataSource = self
}

@IBAction func one4Slider(_ sender: Any) {
    one4Label.text = "\(one4Slider.value)"
}

@IBAction func calculateButton(_ sender: Any) {
    result = factor*(one4num-factory)/per5ft
    output.text = "\(result)"
}
}

The code breaks the "FirstViewController" and seems to invalidate the "numberOfRows" and "titleForRows" statements as well as a cascade of errors below that.

If i implement after those two functions:

 else {
        return capacities[row]
    }
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    if pickerView == oduPicker{
        self.rowSelected = row
        // make anything
    }



@IBOutlet weak var oduPicker: UIPickerView!

@IBOutlet weak var idu1PickerView: UIPickerView!
@IBOutlet weak var idu2PickerView: UIPickerView!
@IBOutlet weak var idu3PickerView: UIPickerView!
@IBOutlet weak var idu4PickerView: UIPickerView!
@IBOutlet weak var idu5PickerView: UIPickerView!

It breaks all the pickerView variables like oduPicker etc.

If I try to bring the statement into the 1st function as such:

var rowSelected: Int?



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

    if pickerView == oduPicker {
        self.rowSelected = row
        return oduList.count
    }
    else if pickerView == idu1PickerView {
        return capacities.count
    }...

It again breaks the "FirstViewController" with the error "Type 'FirstViewController' does not conform to protocol 'UIPickerViewDataSource'"

I'm also forced to put a "!" after "rowSelected" for wrapping/unwrapping. I'm not sure if what this means or if it's important at the moment.

Update:

If I implement per Samuel's suggestion as such:

import UIKit

class FirstViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource { func numberOfComponents(in pickerView: UIPickerView) -> Int { return 1 }

var capacities = ["6","9","12","15","18","24"]
var notUsed = ["N/A"]
var oduList = ["MXZ-2C20", "MXZ-3C24", "MXZ-3C30", "MXZ-5C42"]
var result:Float = 0.0
var one4num:Float = 1.0
var factor:Float = 1.08
var per5ft:Float = 5
var factory:Float = 98

var selectedRow = 1



func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    selectedRow = pickerView.selectedRow(inComponent: index)
    if pickerView == oduPicker {
        return oduList.count
    }
    else if pickerView == idu1PickerView {
        return capacities.count
    }
    else if pickerView == idu2PickerView {

        return capacities.count
    }
    else if pickerView == idu3PickerView {
        if selectedRow  < 2 {
            return 1
        }
        else {
            return capacities.count
        }
    }
    else if pickerView == idu4PickerView {
        if selectedRow < 3 {
            return 1
        }
        else {
            return capacities.count
        }
    }
    else {
        if selectedRow < 4 {
            return 1
        }
        else {
            return capacities.count
        }
    }
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    if pickerView == oduPicker {
        return oduList[row]
    }
    else if pickerView == idu1PickerView {
        return capacities[row]
    }
    else if pickerView == idu2PickerView {
        return capacities[row]
    }
    else if pickerView == idu3PickerView {
        if selectedRow < 2 {
            return notUsed[row]
        }
        else {
            return capacities[row]
        }
    }
    else if pickerView == idu4PickerView {
        if selectedRow < 3 {
            return notUsed[row]
        }
        else {
            return capacities[row]
        }
    }
    else if pickerView == idu5PickerView {
        if selectedRow < 4 {
            return notUsed[row]
        }
        else {
            return capacities[row]
        }
    }
    else {
        return capacities[row]
    }
}




@IBOutlet weak var oduPicker: UIPickerView!

@IBOutlet weak var idu1PickerView: UIPickerView!
@IBOutlet weak var idu2PickerView: UIPickerView!
@IBOutlet weak var idu3PickerView: UIPickerView!
@IBOutlet weak var idu4PickerView: UIPickerView!
@IBOutlet weak var idu5PickerView: UIPickerView!

@IBOutlet weak var one4Label: UILabel!
@IBOutlet weak var one4Slider: UISlider!



@IBOutlet weak var output: UILabel!




override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    self.oduPicker.delegate = self
    self.oduPicker.dataSource = self
    self.idu1PickerView.delegate = self
    self.idu1PickerView.dataSource = self
    self.idu2PickerView.delegate = self
    self.idu2PickerView.dataSource = self
    self.idu3PickerView.delegate = self
    self.idu3PickerView.dataSource = self
    self.idu4PickerView.delegate = self
    self.idu4PickerView.dataSource = self
    self.idu5PickerView.delegate = self
    self.idu5PickerView.dataSource = self
}

@IBAction func one4Slider(_ sender: Any) {
    one4Label.text = "\(one4Slider.value)"
}

@IBAction func calculateButton(_ sender: Any) {
    result = factor*(one4num-factory)/per5ft
    output.text = "\(result)"
}

}

I get an error after the line:

selectedRow = pickerView.selectedRow(inComponent: index)

"Cannot convert value of type '(Any) -> Int' to expected argument type 'Int'"

1
  • See UIPickerViewDelegate and its methods. Commented Oct 24, 2018 at 16:14

1 Answer 1

1

You can use the delegate's methods. The method below can help you. The row parameter specific the row selected by user. You can try:

var rowSelected : Int?

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    if pickerView == idu1PickerView {
       self.rowSelected = row
       // make anything
    }
    ...
}

If you have just one component you can use the method like you wrote:

var selectedRow = pickerView.selectedRow(inComponent: 0)
Sign up to request clarification or add additional context in comments.

3 Comments

See "answer" for further issues using option 1.
Sorry, I don't got it/
took me a while to type it

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.