向静态 UITableView 添加行:获取 NSRangeException

Posted

技术标签:

【中文标题】向静态 UITableView 添加行:获取 NSRangeException【英文标题】:Adding row to Static UITableView: Getting NSRangeException 【发布时间】:2015-06-15 21:10:56 【问题描述】:

我有一个 static UITableView 和两个 sections。当用户点击第 1 节中索引 2 处的单元格时,需要在点击的单元格下方添加一个UITableViewCell。每个后续的单元格点击都会导致在任何已添加的单元格下方添加另一个单元格。

这是我迄今为止尝试过的,但我遇到了 NSRangeException 声明索引 6 超出了可用范围,所以我显然没有以某种方式正确更新行数..

根据Adding unknown number of rows to 'Static Cells' UITableView,我已经覆盖了所有使用 indexPath 的UITableView 方法,但它们的情况与我的略有不同。

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    if section == 1 
        // subTaskRow is an array holding all the indexes of the added cells
        // so I know where to add the next one. I also know how many I've added
        return 6 + subTaskRow.count
     else 
        return super.tableView(tableView, numberOfRowsInSection: section)
    

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) 
    // If the Sub Task cell is picked
    if (indexPath.section == 1 && indexPath.row == 3) 
        // If this is the first subtask we want it to appear under Sub Tasks
        // We know the index of the cell below sub task so we can add it in directly
        if (subTaskRow.count == 0) 
            subTaskRow.addObject(5)
            tableView.insertRowsAtIndexPaths([NSIndexPath(forRow: 5, inSection: 1)], withRowAnimation: .Automatic)
            tableView.reloadData()
        // Other sub tasks should appear below previous sub tasks
         else 
            // The last object in sub tasks will always be the
            // indexPath of the previous added cell
            let row = (subTaskRow.lastObject as! Int) + 1
            subTaskRow.addObject(row)
            tableView.insertRowsAtIndexPaths([NSIndexPath(forRow: row, inSection: 1)], withRowAnimation: .Automatic)
            tableView.reloadData()
        
    

    tableView.deselectRowAtIndexPath(indexPath, animated: true)


// Now we override all the other methods to ensure we don't get a crash
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool 
    return false


override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool 
    return false


override func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle 
    return .None


override func tableView(tableView: UITableView, indentationLevelForRowAtIndexPath indexPath: NSIndexPath) -> Int 
    return super.tableView(tableView, indentationLevelForRowAtIndexPath: indexPath)

我的猜测是在部分中间添加一个单元格不会更新已经存在的单元格的 indexPaths 或其他什么?不过我不知道该怎么做。

【问题讨论】:

你的 cellForRowAtIndexPath 方法是什么样的?您可以将它添加到您的 tableview 方法列表中吗?另外,在界面生成器中,您是否设置了“索引行限制”? @erparker 我实际上并没有使用过,因为它们都是静态单元格,没有什么可配置的......我需要将它用于我要添加的行吗? 我注意到的另一件事是,您是否尝试创建自己的 UITableView 子类?您已经在所有 tableview 数据源和委托方法之前进行了覆盖,如果您只是将 tableview 用作视图控制器的一部分,则不需要。 这是一个 UITableViewController。如果我没有覆盖 swift 对我大喊大叫 是的,没错。我的另一个问题是你为什么在你的 numberOfRowsatIndexPath 方法中调用 super.numberOfRows ?我实际上得到了这个工作,但我不得不改变你处理部分的方式 【参考方案1】:

我得到了这个工作,但这段代码只使用了一个部分:

override func numberOfSectionsInTableView(tableView: UITableView) -> Int 
        // #warning Potentially incomplete method implementation.
        // Return the number of sections.
        return 1
    

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    // subTaskRow is an array holding all the indexes of the added cells
    // so I know where to add the next one. I also know how many I've added
    return 6 + subTaskRow.count


override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) 
    // If the Sub Task cell is picked
    if (indexPath.section == 0 && indexPath.row == 3) 
        // If this is the first subtask we want it to appear under Sub Tasks
        // We know the index of the cell below sub task so we can add it in directly
        if (subTaskRow.count == 0) 
            subTaskRow.append(5)
            tableView.insertRowsAtIndexPaths([NSIndexPath(forRow: 5, inSection: 0)], withRowAnimation: .Automatic)
            tableView.reloadData()
            // Other sub tasks should appear below previous sub tasks
         else 
            // The last object in sub tasks will always be the
            // indexPath of the previous added cell
            let row = subTaskRow.last! + 1
            subTaskRow.append(row)
            tableView.insertRowsAtIndexPaths([NSIndexPath(forRow: row, inSection: 0)], withRowAnimation: .Automatic)
            tableView.reloadData()
        
    

    tableView.deselectRowAtIndexPath(indexPath, animated: true)



override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! UITableViewCell

    cell.textLabel!.text = "the row: \(indexPath.row)"

    return cell

试试这个代码,看看它是否适合你。从这里,您只需要添加代码来处理节,这意味着将代码添加到 numberOfSectionsInTableView。您不应该在这里调用 super.numberOfRowsInTableview,因为如果您有 2 个数据部分,您应该知道每个部分有多少行

【讨论】:

以上是关于向静态 UITableView 添加行:获取 NSRangeException的主要内容,如果未能解决你的问题,请参考以下文章

在运行时从静态 UITableView 中删除行

向 UItableview 添加行并在 Viewcontroller 之间传递数据

尝试在用户向 iOS 中的 UITableView 添加行时动态增加 UITableView 的高度

RxSwift + RxRealm + RxCocoa 向 UITableView 插入行

使用 Restkit 上传图像 - 向 UITableView 添加两行而不是一行

UITableView添加子视图问题