使用Swift中的commitEditingStyle动态删除UITable部分

时间:2015-04-20 12:36:42

标签: ios objective-c xcode uitableview swift

我正在处理一个我无法解决的问题...我有一个名字表,来自DB客户群,每个客户都有一个名称属性和其他数据成员。

我可以成功删除某个部分中的行,但是我无法删除该部分(当该部分中的最后一行被删除时,部分必须消失)。

我得到了:

  

' NSInternalInconsistencyException',原因:'无效更新:无效   部分数量。表中包含的部分数量   更新后的视图(3)必须等于部分的数量   在更新前的表视图中包含(4),加上或减去   插入或删除的部分数量(插入0,删除0)。

我知道该表在数据的幕后进行了一些健全性检查,这应该匹配,但在调用deleteRowsAtIndexPaths之前,我无法确切地说明何时?后?我什么时候应该更新我的财产和/或字典?我应该管理numberOfSectionsInTableView数据源方法吗?

我再说一遍,对于删除它正常工作的行,该表移出行并正确更新。部分的最后一行是交易...

我想我错过了什么,这就是我要问的原因......无法找到任何帮助。

非常感谢你们!

func tableView(tableView: UITableView!, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath!) {
    if (editingStyle == UITableViewCellEditingStyle.Delete) {
        // handle delete (by removing the data from the array and updating the tableview)

        //Check if delete was press
        if editingStyle == .Delete {
            //Delete row from dataSource
            if let tv = tableView
            {

                customerList.removeAtIndex(returnPositionForThisIndexPath(indexPath, insideThisTable: tableView))
                // Deletes the name of the customer from the customer list array, sorted by name

                fillArrayOfNames()
                //Fill the array of names for the sections-table, creating a dictionary with the name initials
                //updated from the customer list array (below)

                tv.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) //Crash in this line

                tableView.reloadData()

        }
    }
}


func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return dictionaryOfPatientsInitials.count
    }

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        var keysFromDictionary = dictionaryOfPatientsInitials.keys.array

        keysFromDictionary.sort(<)
        let keyByOrder = keysFromDictionary[section]
        let arrayInThisSection = dictionaryOfPatientsInitials[keyByOrder]

        return arrayInThisSection!.count
    }

3 个答案:

答案 0 :(得分:2)

你几乎就在那里,但是你需要一种方法来检测一个部分已经消失了,哪一部分已经消失了,你可以调用哪一部分deleteSections

beginUpdate / endUpdate来电中关注更新部分,但不要致电reloadData(请参阅相关方法的文档)

/**
remove customer from model layer

:param: index index of customer to remove

:returns: return section that was removed or nil if none was
*/
func removeCustomer(index:Int)->Int? {

    var removedSectionOrNil:Int? = nil
    //logic to remove customer, rebuild model and detect if section has gone also
    return removedSectionOrNil

}

func tableView(tableView: UITableView!, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath!) {
    if (editingStyle == UITableViewCellEditingStyle.Delete) {
        // handle delete (by removing the data from the array and updating the tableview)

        //Check if delete was press
        if editingStyle == .Delete {
            //Delete row from dataSource
            if let tv = tableView
            {
                tv.beginUpdates()

                let position = returnPositionForThisIndexPath(indexPath, insideThisTable: tableView)
                let removedSection = removeCustomer(position)

                tv.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) //Crash in this line

                if let removedSection = removedSection {
                    tv.deleteSections(sections:NSIndexSet(index: removedSection) as IndexSet, withRowAnimation: .Automatic)
                }

                tv.endUpdates()

            }
        }
}

如果没有看到你的其余代码,这个应该工作,但是当做消失的部分时,tableViews可能会很棘手。

答案 1 :(得分:0)

到目前为止共享我的解决方案......(尚未开始工作)

func removeCustomer(index:Int)->Int? {

        var removedSectionOrNil:Int? = nil

        let customerListOld = customerList
        customerList.removeAtIndex(index)

        let oldArray = CustomerToInitialsArray(customerListOld)
        let newArray = CustomerToInitialsArray(customerList)

        removedSectionOrNil = compareTwoArraysOfSortedKeys(oldArray, newArray: newArray)

        fillArrayOfNames()
        //Fill the array of names for the sections-table, creating a dictionary with the name initials
        //updated from the customer list array (below)

        //logic to remove customer, rebuild model and detect if section has gone also
        return removedSectionOrNil

    }


 func compareTwoArraysOfSortedKeys(oldArray: [String], newArray: [String]) -> Int? {

        //oldArray should be bigger than new or equal
        //if so, that means some value has been dropped out

        if (oldArray.count > newArray.count) {
            for index in 0..<newArray.count {
                if (oldArray[index] != newArray[index]) {
                    return index
                }
            }
            return newArray.count
        }
        return nil
    }

    func returnPositionForThisIndexPath(indexPath:NSIndexPath, insideThisTable theTable:UITableView)->Int{

        var i = 0
        var rowCount = 0

        while i < indexPath.section {

            rowCount += theTable.numberOfRowsInSection(i)

            i++
        }

        rowCount += indexPath.row

        return rowCount
    }

答案 2 :(得分:0)

我正坐在类似的问题上 - 但是我已经从非编程方式解决了这个问题。 我所做的是有两个tableviews,只是列出所有“客户”密钥到他们的详细信息。 (我使用字典中的一个键写入数据库,第二个列出“客户”详细信息 - 每个客户都是一个部分。 然后我在密钥表中使用Checkmark作为表格中单元格的编辑附件。使用删除选项进行编辑将删除密钥,然后我只需删除此代码中的字典项:

    func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
        if editingStyle == UITableViewCellEditingStyle.Delete 
            actDict[keyArray[indexPath.row]] = nil
            keyArray.removeAtIndex(indexPath.row)
            tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
            try! writeFile!.addValuesToUserFile(actDict)

        }

    }

这对我来说完美无瑕。 对不完整的初步答案

抱歉