Ryohei Arai
Ryohei Arai

Reputation: 121

Swift3: Unable to delete rows in a section

I have attempted several possible ways that a selected cell is deleted, but it crashes everytime. I picked some code from other stackoverflow post, but it just failed.

I have created an alphabetic section set of arrays;

sections = [
        Section(title: "A", word: []),
        Section(title: "B", word: []),
        Section(title: "C", word: []),
        Section(title: "D", word: []),
        Section(title: "E", word: []),
        Section(title: "F", word: []),
        Section(title: "G", word: []),
        Section(title: "H", word: []),
        Section(title: "I", word: []),
        Section(title: "J", word: []),
        Section(title: "K", word: []),
        Section(title: "L", word: []),
        Section(title: "M", word: []),
        Section(title: "N", word: []),
        Section(title: "O", word: []),
        Section(title: "P", word: []),
        Section(title: "Q", word: []),
        Section(title: "R", word: []),
        Section(title: "S", word: []),
        Section(title: "T", word: []),
        Section(title: "U", word: []),
        Section(title: "V", word: []),
        Section(title: "W", word: []),
        Section(title: "X", word: []),
        Section(title: "Y", word: []),
        Section(title: "Z", word: [])
    ]

Then, I add some element into the word[]. For example, I add "sunny", it is automatically added into S section. After a UITableView is loaded and when I select the cell to delete, it get crashes saying

reason: 'Invalid update: invalid number of sections. The number of sections contained in the table view after the update (26) must be equal to the number of sections contained in the table view before the update (26), plus or minus the number of sections inserted or deleted (0 inserted, 1 deleted).'

Here is what I did in editingStyle func:

override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {

    if editingStyle == .delete {
        // Delete the row from the data source

        tableView.beginUpdates()

        let indexSet = NSMutableIndexSet()
        indexSet.add(indexPath.section)
        tableView.deleteSections(sections[indexPath.section].words[indexPath.row] as IndexSet, with: UITableViewRowAnimation.fade)

        tableView.endUpdates()

    } else if editingStyle == .insert {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
    }
}

What am I doing wrong here?

Upvotes: 1

Views: 994

Answers (1)

Reinier Melian
Reinier Melian

Reputation: 20804

Hello I had implemented a little scenario with your problem, and this is what i had done

import UIKit

class Section
{
    var title: String  = ""
    var words: [String] = []

    init(title:String,word:[String]) {
        self.title = title
        self.words = word
    }
}

class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {

    @IBOutlet weak var testTableView: UITableView!

    var sections : [Section] = []

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        sections = [
            Section(title: "A", word: ["Avena"]),
            Section(title: "B", word: []),
            Section(title: "C", word: []),
            Section(title: "D", word: []),
            Section(title: "E", word: []),
            Section(title: "F", word: []),
            Section(title: "G", word: []),
            Section(title: "H", word: []),
            Section(title: "I", word: []),
            Section(title: "J", word: []),
            Section(title: "K", word: []),
            Section(title: "L", word: []),
            Section(title: "M", word: []),
            Section(title: "N", word: []),
            Section(title: "O", word: []),
            Section(title: "P", word: []),
            Section(title: "Q", word: []),
            Section(title: "R", word: []),
            Section(title: "S", word: ["Susto"]),
            Section(title: "T", word: []),
            Section(title: "U", word: []),
            Section(title: "V", word: []),
            Section(title: "W", word: []),
            Section(title: "X", word: []),
            Section(title: "Y", word: []),
            Section(title: "Z", word: [])
        ]

        self.testTableView.delegate = self
        self.testTableView.dataSource = self
    }

    public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
        return self.sections[section].words.count
    }


    public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
    {
        let cell = tableView.dequeueReusableCell(withIdentifier: "testCell", for: indexPath) as! TestTableViewCell
        cell.lblWordText.text = self.sections[indexPath.section].words[indexPath.row]
        return cell
    }

    public func numberOfSections(in tableView: UITableView) -> Int
    {
       return self.sections.count
    }


    public func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?
    {
        return self.sections[section].title
    }

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {

        if editingStyle == .delete {
            // Delete the row from the data source

            tableView.beginUpdates()

            let indexSet = NSMutableIndexSet()
            indexSet.add(indexPath.section)

            //let indexSet = sections[indexPath.section].words[indexPath.row] as IndexSet
            //sections.remove(at: indexPath.section)
            sections[indexPath.section].words.remove(at: indexPath.row)
            //tableView.deleteSections(indexSet, with: UITableViewRowAnimation.fade)
            tableView.deleteRows(at: [indexPath], with: .fade)

            tableView.endUpdates()

        } else if editingStyle == .insert {
            // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
        }
    }

    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        return true
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

I hope this helps, this works and was tested

Upvotes: 2

Related Questions