2017-03-07 1 views
1

Ich habe eine Auswahlansicht mit verschiedenen Arrays ausgefüllt, je nachdem, auf welches Textfeld Sie klicken. Wenn ich jedoch die fünfte Zeile des "Untergrund" -Arrays wähle, stürzt die App mit dem Index außerhalb des Bereichsfehlers ab. Es zeigt mir, dass die Zeile int = 4 und die Komponente int = 0 ist. Der Fehler tritt in der Zeile auf, in der die erste if-Anweisung in der Funktion did select row gesetzt ist. Ich habe keine Ahnung, warum dies geschieht ...Index außerhalb des Bereichsfehler bei Verwendung der Auswahlansicht

Hier der entsprechende Code ist:

@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

Wenn Sie Wir tauschen das aktuelle Modell in 'currentData' aus, so dass die korrekte Anzahl immer' currentData.count' ist, was ist der Punkt des großen 'if/else' in' didSelectRow'? Sicher ist 'currentData [row]' immer das gewünschte Datum. Auf diese Weise besteht kein Risiko, das falsche Modellarray und den falschen Indexwert zu erhalten. – matt

+0

FYI - Es ist üblich, Variablen und Methoden mit Kleinbuchstaben zu beginnen. Klassennamen sollten mit Großbuchstaben beginnen. – rmaddy

+0

@rmaddy Einverstanden, aber verstehen Sie, dass dies eine schwierige Konvention für Deutschsprachige ist, deren Sprache es erfordert, mit einem Großbuchstaben zu beginnen. Seine Variablennamen sind einfach _are_ deutsche Wörter und sehen völlig natürlich aus, wenn Sie Deutsch sprechen. – matt

Antwort

0

currentData eine der anderen Arrays sein kann. Und row kann für einen Index größer als einige der Arrays sein. Dies ist die Ursache des Absturzes.

Die richtige Lösung ist zu beheben, wie Sie bestimmen, welches Etikett aktualisiert werden soll.

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 
} 

Obwohl eine bessere Option könnte eine andere Eigenschaft hinzuzufügen, das aktuelle Textfeld zu verfolgen.

var currentField: UITextField? 

Dann textFieldShouldBeginEditing aktualisieren:

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; 
} 

Dann didSelectRow aktualisieren:

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

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

Prost Mate, das hat funktioniert. Entschuldigung dafür, dass ich den offiziellen Stardard nicht mit Großbuchstaben etc. benutze. Ich bin neu zu swift. Ich muss noch viel lernen. – AlexVilla147

0

Das Problem ist, dass dieser Test ausgeführt wird:

if (itemSelected == StadtArray[row]) { 

... aber, wie Sie richtig sagen, die Daten, die tatsächlich in der Auswahlansicht angezeigt werden, sind nicht von StadtArray aber von UntergrundArray. Daher wählen Sie die fünfte Zeile und row ist 4, aber StadtArray hat nur vier Einträge, so Index 4 ist außerhalb der Grenzen; StadtArray gibt es nicht. Und so stürzt du ab.

Sie könnten dies beheben, indem Sie die Tests in aufsteigender Reihenfolge der Array-Größe oder durch Hinzufügen einer Größe Test auf dem Array vor sprechen von [row], aber wie rmaddy richtig sagt, das eigentliche Problem ist, dass Ihr Test für welche Quelle die currentData kommt von ist nur ein schlecht entworfener Test.

Was ich persönlich tun würde, ist dies. Ich würde beseitigen currentData und die fünf Modell-Arrays und als einzelne Array von Arrays meine Modelldaten pflegen:

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"]] 

Nun möchte ich eine einzige Zahl halten, die den Index in model des aktuellen Array:

var currentModel : Int = 0 

Dies macht die Dinge unglaublich einfach und direkt! Die Anzahl der Komponenten würde model[currentModel].count und titleForRowmodel[currentModel][row] würde - und wir konnten die if/else in didSelect, beseitigen, weil model[currentModel] ich nehme direkt in das richtige Modell und so model[currentModel][row] Werke auch dort.

(Obwohl eigentlich der Titel für die Reihe , die Daten, so dass Sie könnten alternative nennen nur titleForRow innerhalb didSelect, kann nicht wahr? Und wieder gäbe es keine Gefahr der Störung.)

Verwandte Themen