0

I'm getting an error when I try to delete a cell from my UITableView. I've looked at numerous links (this one for example is what I'm going off of. Below is my code:

var countdownTime = expirDate - currentDate
    timer.setCountDownTime(countdownTime)
    println("Count : \(self.offers.count)")
    timer.startWithEndingBlock { (countdownTime) -> Void in
        //If the times have expired, then delete the row
        self.tableView.beginUpdates()
        self.offers.removeAtIndex(indexPath.row)
        self.tableView.deleteRowsAtIndexPaths([indexPath.row], withRowAnimation: UITableViewRowAnimation.Fade)
        self.tableView.endUpdates()
    }
timer.start()

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return offers.count
}
//Only one section
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
}

I want to remove the cell when my timer has completed and the offers array is the array that I use to populate the UITableView. I was going off of this Assertion Failure -[UITableView _endCellAnimationsWithContext] which I thought would help me delete/insert rows correctly but I still get an error saying:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (1) must be equal to the number of rows contained in that section before the update (1), plus or minus the number of rows inserted or deleted from that section (1 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'

Any help would be appreciated!

EDIT: An issue I might be having that I am trying to delete the cell while I am inserting the cell into the UITableView. I am inserting the cell, setting the cell contents, then deleting the cell if the timer for that cell has existed for over 24 hours. This is bad because the cell will then try to insert the next cell when it thinks that there is 1 cell in the table view. Are there any better ways to do this?

EDIT 2: Code for inserting into table:

           ...//Code to insert into database
    override func viewDidLoad() {
    super.viewDidLoad()

    //setupOffers()

    setupOffers { (result, offer) -> Void in
        if(result == true){
            //Insert each row one by one.
            var currentCount = self.offers.count
            var indexPaths: [NSIndexPath] = [NSIndexPath]()
            indexPaths.append(NSIndexPath(forRow:currentCount, inSection: 0))
            self.offers.append(offer)
            currentCount++;

            //Update based on each table view index.
            self.tableView.beginUpdates()
            self.tableView.insertRowsAtIndexPaths(indexPaths, withRowAnimation: UITableViewRowAnimation.Bottom)
            self.tableView.endUpdates()
            //Method 2 to update uitableview

            //self.tableView.reloadData()
        }
    }
    // Do any additional setup after loading the view, typically from a nib.
    self.tableView.delegate = self
    self.tableView.dataSource = self
    self.tableView.rowHeight = UITableViewAutomaticDimension
    self.tableView.rowHeight = 145.0

}
Community
  • 1
  • 1
user1871869
  • 3,317
  • 13
  • 56
  • 106
  • you can find here an example to add and delete cells http://stackoverflow.com/a/29807963/2477632 – HamzaGhazouani Apr 29 '15 at 09:15
  • You past an array of integers to delete and not an array of indexPaths Replace that : deleteRowsAtIndexPaths([indexPath.row] by : deleteRowsAtIndexPaths([indexPath] – HamzaGhazouani Apr 29 '15 at 09:20
  • 2
    You are probably changing your `offers` array somewhere else, too. – Sulthan Apr 29 '15 at 09:21
  • 1
    are you inserting row as well? if yes than add your code for inserting row as well as the error suggest (1 inserted, 0 deleted) – Sanjay Mohnani Apr 29 '15 at 09:23
  • 1
    also make sure that the timer is using the main thread to perform the operations. – Sulthan Apr 29 '15 at 09:25
  • @Sulthan you are definitely right. I am inserting a cell, then I set the cell contents, then I see if the timer is greater than 24 hours. If it is greater than 24 hours, I delete it using the code above. This is probably causing the offers array to be changed multiple times before it can update properly. Any ideas on how to fix this? I will add in the code for inserting. – user1871869 Apr 29 '15 at 09:42

3 Answers3

0

Try self.tableView.beginUpdates() after self.offers.removeAtIndex(indexPath.row)

EDIT: Remove beginUpdates and endUpdates, as self.tableView.deleteRowsAtIndexPaths([indexPath.row], withRowAnimation: UITableViewRowAnimation.Fade) should be enough to refresh the table.

EDIT 2: Check that the count of offers is correct after the update. Print its count before and after you delete the item and after return offers.count.

EmirC
  • 161
  • 6
  • I just attempted this but unfortunately that didn't seem to have it work. Any other ideas? – user1871869 Apr 29 '15 at 09:13
  • I have just tried your method to remove `beginUpdates` and `endUpdates` but that too gives me the same error. – user1871869 Apr 29 '15 at 09:19
  • When I try to print out the count, they seem to be the same. I think my issue may be because I am trying to delete the cell while I am inserting the cell into the UITableView. I am inserting the cell, setting the cell contents, then deleting the cell if the timer for that cell has existed for over 24 hours. Are there any better ways to do this? – user1871869 Apr 29 '15 at 09:38
  • Are you starting the timer after inserting the cell? – EmirC Apr 29 '15 at 09:53
  • I check if the current time is less than 1 day ahead of when the object was created. If it is, then I set the timer to whatever the difference between the 1 day ahead of when the object was created minus the current time. If the time is 0 or less though, then I want to delete cell from the UITableView – user1871869 Apr 29 '15 at 09:55
  • When the view first loads (`viewDidLoad`), you don't need to update the table as it will do so anyway. Whether `offers` is populated or not, the table would display a number of cells equal to the count of `offers`, so you don't need to enter a row and update the table one by one in `viewDIdLoad`. You just need to fill up `offers`. On another note, with the 0 condition, you may as well not insert it in the first place. – EmirC Apr 29 '15 at 10:09
  • As for your original question: After removing the item from `offers`, try reloading the table with `reloadData` without beginning/ending updates and `deleteRowsAtIndexPaths` – EmirC Apr 29 '15 at 10:23
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/76565/discussion-between-user1871869-and-emirc). – user1871869 Apr 29 '15 at 17:18
0

Add the statement self.offers.removeAtIndex(indexPath.row) before starting the updates on the table view self.tableView.beginUpdates() as

self.offers.removeAtIndex(indexPath.row)
self.tableView.beginUpdates()

As it could happen that you start the update on table view and the number of rows are returned before deleting the object from the array, and thus could result in inconsistency.

Sanjay Mohnani
  • 5,947
  • 30
  • 46
  • I just tried this but it didn't seem to work. I get the exact same error. Any other ideas? – user1871869 Apr 29 '15 at 09:13
  • @user1871869 replace self.tableView.deleteRowsAtIndexPaths([indexPath.row], withRowAnimation: UITableViewRowAnimation.Fade) with self.tableView!.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: UITableViewRowAnimation.Fade) – Sanjay Mohnani Apr 29 '15 at 09:24
  • I think I know my issue. I think my issue may be because I am trying to delete the cell while I am inserting the cell into the UITableView. I am inserting the cell, setting the cell contents, then deleting the cell if the timer for that cell has existed for over 24 hours. Are there any better ways to do this? – user1871869 Apr 29 '15 at 09:39
0

I believe this is simply a caching problem. Your fetchedResultController is not going to automatically refetch your results as it caches its results. That means that when tableView:numberOfRowsInSection: is called again, the results count is still returning number even though you deleted an item. Use this code...

self.tableView.beginUpdates()
self.tableView!.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: UITableViewRowAnimation.Fade)
self.tableView.endUpdates()

Error when deleting item from tableview in swift

This might helps you :)

Community
  • 1
  • 1
Yuyutsu
  • 2,509
  • 22
  • 38