具有多个组件的动态 PickerView:索引超出范围
Dynamic PickerView with multiple components: Index out of range
我有一个基于此 code 的包含 3 个组件的 PickerView。右侧的两个选择器根据左侧的先前选择更改其内容。
不幸的是,当我将父选择器更改为行数少于预览的另一个选择器时,应用程序崩溃:致命错误:索引超出范围。
我尝试 return 在选择另一个父选择器后将子选择器移到第一个位置,但没有成功。 (请参阅 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)
}
}
当您在 didSelectRow
中调用 reloadAllComponents()
时,您尚未更新选定的行,因此它正在崩溃。
换个顺序应该没问题。
也可能对这里感兴趣。
注意 pickerView.reloadAllComponents()
并非绝对必要,如上文 post 中所指出。您可以重新加载需要更改的那些。
还有一个建议:如果您使用枚举来组织您的组件,那么您的代码会更容易 read/maintain,因此您可以使用 if componentType == .country
(或更好)而不是 if component == 0
然而,例如 switch
)。
我有一个基于此 code 的包含 3 个组件的 PickerView。右侧的两个选择器根据左侧的先前选择更改其内容。 不幸的是,当我将父选择器更改为行数少于预览的另一个选择器时,应用程序崩溃:致命错误:索引超出范围。
我尝试 return 在选择另一个父选择器后将子选择器移到第一个位置,但没有成功。 (请参阅 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)
}
}
当您在 didSelectRow
中调用 reloadAllComponents()
时,您尚未更新选定的行,因此它正在崩溃。
换个顺序应该没问题。
注意 pickerView.reloadAllComponents()
并非绝对必要,如上文 post 中所指出。您可以重新加载需要更改的那些。
还有一个建议:如果您使用枚举来组织您的组件,那么您的代码会更容易 read/maintain,因此您可以使用 if componentType == .country
(或更好)而不是 if component == 0
然而,例如 switch
)。