2017-03-07 47 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,難道不是嗎?而且又不會有什麼差錯的危險。)