1

In my app I have a text field (Distance) that has segmented control to choose the unit reference (Km/Mi):

enter image description here

I have another text field (pace) that show a UIPickerView. This picker view can be populated with 2 arrays based on what unit the user selected. Everything works except that, even when the picker view is not shown and I change the selection, the array change only when I start scroll the picker view. So initially it shows the array in km even if I selected Mi and then it changes when I start moving the picker.

Initially I set a variable for the unit reference and the 2 arrays

var unitReference = "Km" // this is the initial selection on the segmented control 
let paceKmArray = [" ", "Relaxing(less than 15km/h)", "Easy(15km/h-20km/h)","Medium(20km/h-25km/h)","Nice(25km/h-30km/h)","Fast(30km/h-35km/h)", "Very Fast(>35km/h)"]
let paceMiArray = [" ", "Relaxing(less than 10 mi/h)", "Easy(10mi/h-13mi/h)","Medium(13mi/h-16mi/h))","Nice(16mi/h-19mi/h))","Fast(19mi/h-12mi/h))", "Very Fast(>22mi/h)"]

then in viewDidLoad

unitReferenceSegmentedControl.addTarget(self, action: "unitChanged:", forControlEvents: .ValueChanged);

which call this method to changed the unit reference

func unitChanged(sender:UISegmentedControl){

    if sender.selectedSegmentIndex == 0{
        unitReference = "Km"
        print(unitReference)

    }

    if sender.selectedSegmentIndex == 1{

        unitReference = "Mi"

        print(unitReference)    
    }
}

And the picker view methods

func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {

    return 1

}

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

    if pickerView.tag == 0{
        return rideTypeArray[row]
    }

    if pickerView.tag == 1{
        if unitReference == "Km"{

        return paceKmArray[row]
        }
        if unitReference == "Mi"{

         return paceMiArray[row]
        }
    }

        return ""

}

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

    if pickerView.tag == 0{

    return rideTypeArray.count
    }
    if pickerView.tag == 1{

        if self.unitReference == "Km"{

            return paceKmArray.count
        }
        if self.unitReference == "Mi"{

            return paceMiArray.count
        }


    }
    return 0
}

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

    if pickerView.tag == 0{
        rideTypeTextField.text = rideTypeArray[rideTypePickerView!.selectedRowInComponent(0)] as String   

    }

    if pickerView.tag == 1{

        if unitReference == "Km"{

            paceTextField.text = paceKmArray[pacePickerView!.selectedRowInComponent(0)] as String
        }
        if unitReference == "Mi"{

            paceTextField.text = paceMiArray[pacePickerView!.selectedRowInComponent(0)] as String
        }     

    }

}

I am not sure this is the best way to do it. If there is a more elegant way to do it, I will be more than happy to learn it.

4
  • If i have to do this, i would take a third array and treat this as the single datasource while switching between paceKmArray and paceMiArray upon segment selection. Commented Oct 12, 2015 at 6:58
  • @Gandalf thanks, I also \tried to do that but the behaviour didn't change Commented Oct 12, 2015 at 6:59
  • You are not calling reloadAllComponents on your picker when you change the segment selection. Call it from unitChanged: as last line. Commented Oct 12, 2015 at 7:06
  • of course!!! ;-) it works perfectly now! If you answer I will selected it. I added pacePickerView.reloadAllComponents() to the unitChanged method Commented Oct 12, 2015 at 7:11

1 Answer 1

1

You are not seeing the changes in your picker view because you are not reloading the data after the datasource is changed. Just call reloadAllComponents on your pickerView once you have changed the datasource and you are good to go.

func unitChanged(sender:UISegmentedControl) {
    //Your previous code for changing the datasource array.

    //Now reload the UIPickerView
    pacePickerView.reloadAllComponents()
}

One more suggestion i would like to give is that if in both the datasource array's have same set of key value pairs then you should keep a 3rd array as the ultimate datasource and switch it with the respective arrays from your unitChanged: method. That way you won't need to have an if condition every now and then to get the current set of data.

Sign up to request clarification or add additional context in comments.

Comments

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.