错误:索引超出范围UITableView

时间:2016-06-05 17:27:45

标签: ios swift uitableview

我正在创建一个使用自定义单元格的应用。我还有这些UITextView,如果您输入一个单词,那么该单词应该转到我在自定义单元格中创建的四个标签之一。我仍然在编码,但我收到错误说"错误:索引超出范围"。

这是代码,我还评论了它给出错误的位置

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) ->
    UITableViewCell{

        let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! TableView

        cell.lbl.text = todolist[indexPath.row]
        cell.lbl2.text = todolist2[indexPath.row] // This is the error code
        cell.lbl3.text = todolist3[indexPath.row]
        cell.lbl4.text = todolist4[indexPath.row]

        return cell   
}

这是我附加文字的地方

@IBAction func ClickedforSelection(sender: AnyObject) {

    todolist.append(txt.text!)
    todolist2.append(txt1.text!)
    todolist3.append(txt2.text!)
    todolist4.append(txt3.text!)

    self.view.endEditing(true)
    txt.text = ""
    txt1.text = ""
    txt2.text = ""
    txt3.text = ""


    NSUserDefaults.standardUserDefaults().setObject(todolist, forKey: "list")
    NSUserDefaults.standardUserDefaults().setObject(todolist2, forKey: "list2")
    NSUserDefaults.standardUserDefaults().setObject(todolist3, forKey: "list3")
    NSUserDefaults.standardUserDefaults().setObject(todolist4, forKey: "list4")

这是我的NumberofRowsInSection

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{


        return todolist.count

}

我猜想它可能是indexPath.row的重用。任何解决方案?

1 个答案:

答案 0 :(得分:1)

如果numberOfRowsInSection返回todolist.count,则表示您正在访问单元格中的todolist2。如果todolist有2个项目并且todolist2有1个项目,它将执行此操作,因为您正在尝试访问不存在的列表中的项目。在第一次调用cell.lbl.text时放置一个断点并检查每个数组(todolist,todolist1等等)。你应该看到todolist2没有记录任何" row"它的来电。如果是这种情况,您应该在调用它之前测试它。 (验证todolist2.count中有足够的项目 - 或者更好的是,将代码更改为没有4个数组跟踪1行(转换为具有所有4个值的某种类型的结构,或类似的东西)。

首先,通过注释掉行来更改以下代码:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) ->
    UITableViewCell{

        let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! TableView

        cell.lbl.text = todolist[indexPath.row]
   //     cell.lbl2.text = todolist2[indexPath.row] // This is the error code
   //     cell.lbl3.text = todolist3[indexPath.row]
   //     cell.lbl4.text = todolist4[indexPath.row]

        return cell   
}

测试以验证现有代码(应该可以工作但当然不会更新标签。) 然后添加代码以打印每个数组中的项目数:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) ->
    UITableViewCell{

        let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! TableView

        cell.lbl.text = todolist[indexPath.row]
   //     cell.lbl2.text = todolist2[indexPath.row] // This is the error code
   //     cell.lbl3.text = todolist3[indexPath.row]
   //     cell.lbl4.text = todolist4[indexPath.row]

  print("Row: \(indexPath.row)")
  print("List 1: \(todolist.count)")  //this will print to the console
  print("List 2: \(todolist2.count)")
  print("List 3: \(todolist3.count)")
  print("List 4: \(todolist4.count)")

        return cell   
}

您可能会看到的是,他们没有相同数量的商品,并且只要他们排出"行"等于或大于项目数,它将打破。请记住,Row从零开始,而计数从1开始。

如果这是你找到的,那么在将值添加到todolist数组的代码中存在问题。如果你想看看如何将它转换为结构,我可以为你发布。

转换为struct

单击某些内容时执行的代码:

@IBAction func ClickedforSelection(sender: AnyObject) {

表示每次都会向每个4个转换者写入一个值。虽然我没有完整的要求,但如果这是您想要做的,那么您可以实现结构。将此代码放入其自己的ToDoList.swift文件(理想情况下):

struct ToDoListItem {
    var listItem: String?
    var list1Item: String?
    var list2Item: String?
    var list3Item: String?
}

然后用一个单词替换你定义todolislt数组(所有4个数组)的位置:

var listItems = [ToDoListItem]()  //creates an array of ToDoListItems and initializes it with no values

然后在ClickedForSelection函数中,将其更改为:

let listItem = ToDoListItem(listItem: txt.text, list1Item: txt1.text, list2Item: txt2.text, list3Item: txt3.text) 
listItems.append(listItem)  //add it to your array

//todolist.append(txt.text!)
//todolist2.append(txt1.text!)
//todolist3.append(txt2.text!)
//todolist4.append(txt3.text!)

self.view.endEditing(true)
txt.text = ""
txt1.text = ""
txt2.text = ""
txt3.text = ""

//  This routine will need to be updated.  Leaving that for you to figure out :)
//    NSUserDefaults.standardUserDefaults().setObject(todolist, forKey: "list")
//  NSUserDefaults.standardUserDefaults().setObject(todolist2, forKey: "list2")
//    NSUserDefaults.standardUserDefaults().setObject(todolist3, forKey: "list3")
//    NSUserDefaults.standardUserDefaults().setObject(todolist4, forKey: "list4")

...然后numberOfRowsInSection更改为:

return listItems.count

...然后cellForRowAtIndexPath更改为:

    let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! TableView

    let listItem = listItems[indexPath.row]

    cell.lbl.text = listItem.listItem ?? ""  // Since listItems.listItem is an optional value, ?? unwraps it safely.  If it is nill, it uses "" instead
    cell.lbl2.text = listItem.list1Item ?? ""
    cell.lbl3.text = listItem.list2Item ?? ""
    cell.lbl4.text = listItem.list3Item ?? ""

    return cell   

再次......我会强烈考虑你每次为所有4个列表存储一个todolist的值(如果它是一个todo列表应用程序,似乎这可能不太理想?)