当我在按钮操作上从 TableView 中删除单元格时,应用程序崩溃了 - iOS Swift

Posted

技术标签:

【中文标题】当我在按钮操作上从 TableView 中删除单元格时,应用程序崩溃了 - iOS Swift【英文标题】:When i remove cell from TableView on button action the app is crashed - iOS Swift 【发布时间】:2016-07-09 10:46:44 【问题描述】:

我试图从TableViewController 中删除一个单元格。每次我滑动并按下删除按钮时都会发生崩溃。

这是崩溃日志:

由于未捕获的异常而终止应用程序 'NSInternalInconsistencyException',原因:'无效更新:无效 第 0 节中的行数。包含在第 0 节中的行数 更新后的现有节(10)必须等于 更新前该部分中包含的行 (10),加号或减号 从该部分插入或删除的行数(0 插入, 1 已删除)并加上或减去移入或移出的行数 该部分(0 移入,0 移出)。'

这是我的UITableView 函数。

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return 10

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

    //Cell configuration.
    myCell.selectionStyle = .None
    myCell.containerView.layer.borderColor = UIColor(hex: 0x3399CC).CGColor
    myCell.containerView.layer.borderWidth = 1
    myCell.containerView.layer.cornerRadius = 10
    myCell.containerView.clipsToBounds = true
    myCell.servicePrice.text = "\(indexPath.row)"
    myCell.serviceCurrency.text = "KWD"
    myCell.serviceTitle.text = "Building ios Application"
    myCell.serviceDescription.text = "This is a service description This is a service description This is a service description This is a service description This is a service description This is a service description This is a service description This is a service description This is a service description"
    return myCell

override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool 
    return true

override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) 

    if editingStyle == .Delete 
        tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
    


可能是什么原因?

【问题讨论】:

【参考方案1】:

请动态添加您的numberOfRowsInSection。它不是静态的。

使用返回 10 的数组 insted。并在编辑样式中删除时删除对象。

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return yourArray.count


override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) 

    if editingStyle == .Delete 
        tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)

// remove object from array here

    


错误原因:你的情况

首先你的表格单元格数是 10。 当您删除单元格时,您的单元格被删除但计数为 10。它已磨损,否则将您的计数减少到 9。

【讨论】:

【参考方案2】:

记录已删除单元格的数量,并从数组中删除相同数量的单元格(用于填充表格视图)。

【讨论】:

【参考方案3】:

从 tableview 中删除行后,您还必须更新 numberOfRowsInSection 值。这就是为什么你会崩溃。

let rows=10
    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        return rows
    
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
        let myCell = tableView.dequeueReusableCellWithIdentifier(cellID, forIndexPath: indexPath) as! PredefinedServicesCell

        //Cell configuration.
        myCell.selectionStyle = .None
        myCell.containerView.layer.borderColor = UIColor(hex: 0x3399CC).CGColor
        myCell.containerView.layer.borderWidth = 1
        myCell.containerView.layer.cornerRadius = 10
        myCell.containerView.clipsToBounds = true
        myCell.servicePrice.text = "\(indexPath.row)"
        myCell.serviceCurrency.text = "KWD"
        myCell.serviceTitle.text = "Building iOS Application"
        myCell.serviceDescription.text = "This is a service description This is a service description This is a service description This is a service description This is a service description This is a service description This is a service description This is a service description This is a service description"
        return myCell
    
    override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool 
        return true
    
    override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) 

        if editingStyle == .Delete 
            tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
            rows-=1
        

    

【讨论】:

【参考方案4】:

根据崩溃日志,您应该在编辑后更新行数

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return 10

【讨论】:

【参考方案5】:

删除单元格后,不能将单元格数返回为 10。应该小于删除前的单元格数。

【讨论】:

【参考方案6】:

您必须更新数据源以匹配表格视图的行/节数,并使用 beginUpdate 和 endUpdate 更新表格视图显示。像这样:

override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) 

    if editingStyle == .Delete 
        tableView.beginUpdate() //optional
        tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
        //TODO ... add your code to update data source here

        tableView.endUpdate() //optional
    


【讨论】:

有一个常见的误解:单个操作根本不需要begin/endUpdates。只有多个可能相互干扰的插入/删除/移动操作才需要它。 开始/结束更新不仅用于插入/删除多行/部分,而且还会更新屏幕中可见的行的高度。否则,我同意不需要一行的操作。【参考方案7】:

您不能向您的 numberOfRowsInSection 声明 静态值,然后通过删除 deleteRowsAtIndexPaths 的行来更改它 (10 - 1),numberOfRowsInSection 保持 10 并且您的行变为 9 所以您遇到此类问题,请进行这些更改以具有动态值

var totalRows: Int = 10

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return self.totalRows


override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) 

    if editingStyle == .Delete 
        if self.totalRows > 0  // This limit your deletion to avoid a crash
            tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
            self.totalRows -= 1
        
    


通常最好处理数据源数组来维护您的信息以显示在每个单元格中,因此请考虑使用数组来执行此操作,以便您可以使用它的count 属性并在删除单元格时删除它的元素。

【讨论】:

【参考方案8】:

您的numberOfRowsInSection 应该是动态的而不是静态的。所以,用yourdataName.remove(at:indexPath.row)删除动态数组中的数据

示例;

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        return yourdataName.count;
    

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) 
                if editingStyle == UITableViewCellEditingStyle.delete 
                    yourdataName.remove(at:indexPath.row)
                    tableView.deleteRows(at: [indexPath], with: UITableViewRowAnimation.automatic)
                
            

【讨论】:

以上是关于当我在按钮操作上从 TableView 中删除单元格时,应用程序崩溃了 - iOS Swift的主要内容,如果未能解决你的问题,请参考以下文章

表视图,如何将删除按钮放在前面?

当我点击 2 个 TableView 控制器之间的“didSelectRowAt indexPath”中的单元格时,我需要执行后退按钮操作

如何通过单击单元格中的按钮来删除 tableView 中的单元格?使用核心数据

在表格视图中删除没有编辑按钮的单元格?

删除单元格后刷新tableView

无法从swift ios中的一段tableview中删除单元格