2017-03-07 78 views
1

我使用不同的数组填充选取器视图,具体取决于您单击哪个文本字段。但是,无论何时我选择“Untergrund”数组的第五行,该应用程序都会崩溃,索引超出范围错误。它显示了行int = 4和组件int = 0。错误发生在第一个if语句在did select行函数中设置的行中。我不知道为什么会这样......使用选取器视图时指数超出范围错误

下面是相关代码:

@IBOutlet weak var Stadt: UITextField! 
@IBOutlet weak var Strasse: UITextField! 
@IBOutlet weak var Platzart: UITextField! 
@IBOutlet weak var Groesse: UITextField! 
@IBOutlet weak var AnzToreKoerbe: UITextField! 
@IBOutlet weak var Untergrund: UITextField! 

// Variable für die Firebase Database 

override func viewDidLoad() { 
    super.viewDidLoad() 

    Stadt.delegate = self 
    Untergrund.delegate = self 
    Groesse.delegate = self 
    AnzToreKoerbe.delegate = self 
    Platzart.delegate = self 
    Picker.delegate = self 
} 

@IBOutlet weak var Picker: UIPickerView! 

var currentData = [""] 

let UntergrundArray = ["Asphalt", "Kunstrasen Sand", "Kunstrasen Granulat", "Rasen", "Tartan", " "] 
let StadtArray = ["Norderstedt", "Hamburg", "Berlin", "München"] 
let GroesseArray = [ "2 vs 2", "3 vs 3", "4 vs 4", "5 vs 5"] 
let AnzTorKoerbe = ["1", "2", "3", "4"] 
let Art = ["Fußball", "Basketball"] 

func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool{ 
    if textField.tag == 1{ 
     currentData = StadtArray 
    }else if textField.tag == 2{ 
     currentData = UntergrundArray 
    }else if textField.tag == 3 { 
     currentData = GroesseArray 
    }else if textField.tag == 4 { 
     currentData = AnzTorKoerbe 
    }else if textField.tag == 5 { 
     currentData = Art 

    } 

    Picker.reloadAllComponents() 

    return false; 
} 

func numberOfComponents(in pickerView: UIPickerView) -> Int { 
    return 1 
} 

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { 
    return currentData.count 
} 

func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { 
    return currentData[row] 
} 

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { 
    let itemSelected = currentData[row] 

    print(itemSelected) 

    if (itemSelected == StadtArray[row]) { 
     Stadt.text = StadtArray[row] 
    }else if (itemSelected == UntergrundArray[row]) { 
     Untergrund.text = UntergrundArray[row] 
    }else if (itemSelected == GroesseArray[row]) { 
     Groesse.text = GroesseArray[row] 
    }else if (itemSelected == AnzTorKoerbe[row]) { 
     AnzToreKoerbe.text = AnzTorKoerbe[row] 
    }else { 
     Platzart.text = Art[row] 
    } 
} 
+0

如果您将当前模型交换到'currentData'中,以便正确的计数总是'currentData.count','didSelectRow'中的大'if/else'的指向是什么?当然'currentData [row]'总是所需的数据。这样就不会有得到错误的模型数组和错误的索引值的风险。 – matt

+0

仅供参考 - 标准的做法是将变量和方法命名为以小写字母开头。类名应以大写字母开头。 – rmaddy

+0

@rmaddy同意,但要理解这对于德语人来说是一个困难的惯例,他们的语言要求以大写字母开头。如果你懂德语,他的变量名简直就是德语单词,看起来完全自然。 – matt

回答

0

currentData可以是其他阵列中的任何一个。并且row可以用于比一些阵列更大的索引。这是事故的原因。

正确的解决方案是解决如何确定要更新哪个标签。

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { 
    let itemSelected = currentData[row] 

    if currentData === StadtArray { 
     Stadt.text = itemSelected 
    } else if currentData === UntergrundArray { 
     Untergrund.text = itemSelected 
    } else ... and the others as needed 
} 

虽然更好的选择可能是添加另一个属性来跟踪当前文本字段。

var currentField: UITextField? 

然后更新textFieldShouldBeginEditing

func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool{ 
    currentField = textField 
    if textField.tag == 1 { 
     currentData = StadtArray 
    } else if textField.tag == 2 { 
     currentData = UntergrundArray 
    } else if textField.tag == 3 { 
     currentData = GroesseArray 
    } else if textField.tag == 4 { 
     currentData = AnzTorKoerbe 
    } else if textField.tag == 5 { 
     currentData = Art 
    } 

    Picker.reloadAllComponents() 

    return false; 
} 

然后更新didSelectRow

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { 
    let itemSelected = currentData[row] 

    if let currentField = currentField { 
     currentField.text = itemSelected 
    } 
} 
+0

干杯队友,工作。对不起使用大写字母等官方stamdard我是新的迅速。还有很多东西需要学习。 – AlexVilla147

0

的问题是,正在执行这个测试:

if (itemSelected == StadtArray[row]) { 

...但正如你所说的,实际显示在选取器视图中的数据是来自StadtArray的而不是来自UntergrundArray的。因此,您选择第五行并且row为4,但StadtArray只有四个条目,因此索引4超出了界限;没有StadtArray [4]这样的东西。所以你崩溃了。

你可以通过设置在数组大小的升序测试解决这个问题,或者通过[row]说话前先加入阵列上的规模试验,但作为rmaddy正确地说,真正的问题是,你的测试,其源currentData来自只是一个设计不好的测试。

我个人会做的是这样的。我将消除currentData和五个模型阵列,以及保持我的模型数据作为单个阵列阵列:

let model = [["Asphalt", "Kunstrasen Sand", "Kunstrasen Granulat", "Rasen", "Tartan", " "], ["Norderstedt", "Hamburg", "Berlin", "München"], [ "2 vs 2", "3 vs 3", "4 vs 4", "5 vs 5"], ["1", "2", "3", "4"], ["Fußball", "Basketball"]] 

现在我将保持表示该索引单号到当前阵列的model

var currentModel : Int = 0 

这使得事情变得非常简单直接!组件的数目将是model[currentModel].counttitleForRowmodel[currentModel][row] - 我们可以消除didSelectif/else,因为model[currentModel]把我们直接到正确的模型等model[currentModel][row]的作品也有。

(虽然实际上,标题为行数据,所以你可以替代就叫titleForRowdidSelect,难道不是吗?而且又不会有什么差错的危险。)