我创建了一个包含 2 个具有不同数据源的组件的选择器 View :
func pickerView(pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusingView view: UIView?) -> UIView {
let pickerLabel = UILabel()
let titleLabel = firstFieldArray[row]
let titlelabel2 = secondFieldArray[row]
if component == 0 {
let myTitle = NSAttributedString(string: titleLabel, attributes: [NSFontAttributeName:UIFont(name: "Georgia", size: 15.0)!,NSForegroundColorAttributeName:UIColor.blackColor()])
pickerLabel.attributedText = myTitle
} else {
let myTitle = NSAttributedString(string: titlelabel2, attributes: [NSFontAttributeName:UIFont(name: "Georgia", size: 15.0)!,NSForegroundColorAttributeName:UIColor.blackColor()])
pickerLabel.attributedText = myTitle
}
return pickerLabel
}
这是我的数据模型:
class professionArrays {
func professsionValues() -> [String] {
return ["Engineer", "Information Technology", "Teacher"]
}
func subProfessionValues(profession: String) -> [String] {
if profession == "Engineer" {
return ["Electrical Engineer","Sex Engineer","Civil Engineer","Software Engineer"]
} else if profession == "Information Technology" {
return ["IT Programmer","UI/UX Designer","Tester/Debugger"]
} else {
return ["English Teacher", "Math Teacher", "Physics Teacher"]
}
}
}
当我选择 Engineer、Information Technology 和 Teacher 时,Picker View 显示数组,它在第二个组件中显示它们的 subProfessional 值。
错误被触发,例如当我选择信息技术并在第一个组件中选择工程师时,当我滑动第二个组件值时发生错误:
error : fatal error: Array index out of range
编辑:didSelectRow 委托(delegate)中的代码
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if component == 0 {
let professionAndSubProfession = professionArrays()
let currentValue = firstFieldArray[row]
secondFieldArray = professionAndSubProfession.subProfessionValues(currentValue)
pickerView.reloadAllComponents()
firstProfessionCurrentValue = firstFieldArray[row]
print(firstProfessionCurrentValue)
selectedProfessionLabel.text = firstProfessionCurrentValue
professionTextfield.text = firstProfessionCurrentValue
} else {
secondSubProfessionCurrentValue = secondFieldArray[row]
selectedSubProfessionLabel.text = secondSubProfessionCurrentValue
professionTextfield.text = "\(firstProfessionCurrentValue!) - \(secondSubProfessionCurrentValue!)"
print(secondSubProfessionCurrentValue)
pickerView.reloadAllComponents()
}
}
最佳答案
工程师的子职业在其数组中有 4 个值,从您与我们共享的代码中,我可以看出这是唯一可能导致该错误的问题。
如果 UIPickerView 试图在第二个组件中显示第 4 行,它将调用委托(delegate)(如您发布的那样)。在该实现中,您调用 firstFieldArray[row]。此时行为 3,但 firstFieldArray 只有 3 个值,因此此时它的最大索引为 2。
简而言之,如果组件为 1,则不要创建 titleLabel;否则,如果组件为 0,则不要创建 titleLabel2。如果您不确定数组是否包含您尝试获取的值的数量的索引,做一些防御性编码:
// Check if the array holds the same or more values then 'row'
if array.count > row {
return array[row]
}
编辑
这是一个关于如何改进委托(delegate)实现的示例。 这样,您的代码就不会尝试从错误的数组中获取项目。每次从选取器中选择一个新项目时,您已经重新加载了 pickerView 组件,因此它应该再次调用 DataSource & Delegates。
// UIPickerViewDataSource
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int
if component == 0 {
return firstFieldArray.count
} else {
return secondFieldArray.count
}
}
//UIPickerViewDelegate
func pickerView(pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusingView view: UIView?) -> UIView {
let pickerLabel = UILabel()
if component == 0 {
// By placing it within the if-statement, this array won't be searched by index unnecassary.
// So even if the second component would hold 4 or more items, it won't try to fetch 4th or higher index from this first array.
let titleLabel = firstFieldArray[row]
let myTitle = NSAttributedString(string: titleLabel, attributes: [NSFontAttributeName:UIFont(name: "Georgia", size: 15.0)!,NSForegroundColorAttributeName:UIColor.blackColor()])
pickerLabel.attributedText = myTitle
} else {
let titlelabel2 = secondFieldArray[row]
let myTitle = NSAttributedString(string: titlelabel2, attributes: [NSFontAttributeName:UIFont(name: "Georgia", size: 15.0)!,NSForegroundColorAttributeName:UIColor.blackColor()])
pickerLabel.attributedText = myTitle
}
return pickerLabel
}
关于ios - Pickerview 委托(delegate) UIView : array index out of range,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32604547/