具有多个组件的动态 PickerView:索引超出范围

Posted

技术标签:

【中文标题】具有多个组件的动态 PickerView:索引超出范围【英文标题】:Dynamic PickerView with multiple components: Index out of range 【发布时间】:2020-04-17 21:41:46 【问题描述】:

我有一个基于 code 的包含 3 个组件的 PickerView。右侧的两个选择器根据左侧的先前选择更改其内容。 不幸的是,当我将父选择器更改为另一个比预览行少的父选择器时,应用程序崩溃:????致命错误:索引超出范围。

在选择另一个父选择器后,我尝试将子选择器返回到它们的第一个位置,但没有成功。 (请看下didSelectRow

你有别的想法吗?

func numberOfComponents(in pickerView: UIPickerView) -> Int 
    return 3


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

    if component == 0 
        return countries.count
     else if component == 1 
        let selectedCountry = pickerView.selectedRow(inComponent: 0)
        return countries[selectedCountry].cities.count
     else 
        let selectedCountry = pickerView.selectedRow(inComponent: 0)
        let selectedCity = pickerView.selectedRow(inComponent: 1)
        return countries[selectedCountry].cities[selectedCity].posts.count
    


func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? 
    if component == 0 
        return countries[row].name
     else if component == 1
        let selectedCountry = pickerView.selectedRow(inComponent: 0)
        return countries[selectedCountry].cities[row].name
     else 
        let selectedCountry = pickerView.selectedRow(inComponent: 0)
        let selectedCity = pickerView.selectedRow(inComponent: 1)
        return countries[selectedCountry].cities[selectedCity].posts[row]
    



func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) 
    pickerView.reloadAllComponents()
    if component == 0 
        pickerView.selectRow(0, inComponent: 1, animated: true)
        pickerView.selectRow(0, inComponent: 2, animated: true)
     else if component == 1 
        pickerView.selectRow(0, inComponent: 2, animated: true)
    

【问题讨论】:

崩溃发生在哪一行?当它说它超出范围时它有什么索引? @shim 这里是消息的截图:i.stack.imgur.com/GY5V0.png。它发生在numberOfRowsInComponent 下。我认为需要在构建新的选择器列表之前更新所选行的位置。但我不知道如何正确地做到这一点。 当您在didSelectRow 中调用reloadAllComponents() 时,您尚未更新所选行。 谢谢@shim!我更改了didSelectRow 下的顺序。现在我最后打电话给reloadAllComponents()。它有效! 【参考方案1】:

当您在 didSelectRow 中调用 reloadAllComponents() 时,您尚未更新选定的行,因此它会崩溃。

换个顺序应该没问题。

Reset the value of the 1st component of UIPickerView when component 0 is changed 可能在这里也很有趣。

注意pickerView.reloadAllComponents() 不是绝对必要的,正如上面帖子中所指出的那样。您可以重新加载需要更改的内容。

还有一个建议:如果您使用枚举来组织您的组件,那么您的代码会更容易阅读/维护,因此您可以使用if componentType == .country(或者更好的是switch)而不是if component == 0,例如。

【讨论】:

再次感谢,我会检查一下。

以上是关于具有多个组件的动态 PickerView:索引超出范围的主要内容,如果未能解决你的问题,请参考以下文章

设置UIPickerView的默认值:索引超出范围

设置 UIPickerView 的默认值:超出范围的索引

Vue.js - 具有动态组件的多个事件

分段选择器视图选择具有相同索引的部分中的所有行

致命错误:追加数组时数组索引超出范围

具有多个文本字段输入视图的多个选取器视图 Swift