Search code examples
swiftxcodeuipickerview

UIPickerView wait with didSelect until scrolling animation is done


I have two UIPickerViews: pickerOne and pickerTwo. The contents of pickerTwo depend on what was selected in pickerOne. The name of the selected item for each picker is displayed in a UITextField.

An example of the dependency:

If pickerOne selects x, then pickerTwo will display element1, element2, and element3.

If pickerOneselects y, then pickerTwo will display element4, element5, and element6.

I use the following code to do this:

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    if pickerView === pickerOne {
        textFieldOne.text = pickerOneData[row].name

        pickerTwoData = // Update the data.
        pickerTwo.selectRow(0, inComponent: 0, animated: false)
    }
    else if pickerView === pickerTwo {
        textFieldTwo.text = pickerTwoData[row].name
    }
}


func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    if pickerView === pickerOne {
        return pickerOneData[row].name
    }
    else if pickerView === pickerTwo {
        return pickerTwoData[row].name
    }
}

Now my problem is that these pickers act very weirdly if I select a row in pickerOne for which there is only one row in pickerTwo.

If i select a row in pickerOne which has several rows in pickerTwo, and then select the row in pickerOne which only has one row in pickerTwo. Then I can get a index out of range error depending on what I do next.

If I close the UIPickerView (self.view.endEditing(true)) then there are no problems, but if I just select the row in pickerOne which has only one row in pickerTwo the error happens.

I suspect this has something to do with the animation which is played when you swipe up on a UIPickerView which makes it scroll since it doesn't update the textfield until it has stopped scrolling.

I'd really appreciate if someone can point me in the right direction.


Solution

  • I managed to fix the bug but I'm still very confused. I changed the code in titleForRow so that it now says:

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        if pickerView === pickerOne {
            let name = pickerOneData[row].name
            return name
        }
        else if pickerView === pickerTwo {
            return pickerTwoData[row].name
        }
    }
    

    All I changed was to save name in a variable first then it worked.