SwipeCellKit crash when try to delete - ios

Hello I am using SwipeCellKit for my UITableView. I want to do the deletion when swipe the cell. This is how I handle the delete part. self.deleteLeave() is calling to web service and delete the selected leave entry in the server side. Then if its successfully deleted in the server side I want to delete that object from the current array and update my UITableView. But my problem is when I swipe and click on the delete button or else dragged it for some extent app is crashing by giving an exception.
Error
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 (0 inserted,
1 deleted) and plus or minus the number of rows moved into or out of
that section (0 moved in, 0 moved out).'
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> [SwipeAction]? {
guard orientation == .right else { return nil }
let deleteAction = SwipeAction(style: .destructive, title: "Delete") { action, indexPath in
// handle action by updating model with deletion
self.com.showProgress()
let dict=self.arrayPendings[indexPath.row] as! [String:Any]
if let reid=dict["RequestId"] as? Int
{
self.selectedReqID=String(reid)
}
self.deleteLeave(){ (status) in
if(status)
{
let delete = SwipeAction(style: .destructive, title: nil) { action, indexPath in
self.com.removeProgress()
self.arrayPendings.remove(at: indexPath.row)
self.tblPendingLeaves.beginUpdates()
//self.tblPendingLeaves.insertRows(at: [IndexPath(row: 0, section: 1)], with: .automatic)
self.tblPendingLeaves.deleteRows(at: [indexPath], with: .fade)
action.fulfill(with: .delete)
self.tblPendingLeaves.endUpdates()
}
}
}
}
// customize the action appearance
deleteAction.image = UIImage(named: "Delete")
return [deleteAction]
}

I have the same problem.
When i call delete it crash and show me the same error.
What i dis is:
delete data from tableView then delete the same data from myDataSource(for example: remove data from array). This will handle your case but it will not refresh the table. (If you close and reopen the project it will delete it from table view).
So check the connections between your data and your table.

Related

Tableview deleting rows and sections

I've implemented the following deleting mechanism: on delete action tableView deletes selected rows and if section does not have any rows it will be deleted.
My mechanism looks like this:
guard let selectedRows = self.tableView.indexPathsForSelectedRows,
let indexPath = self.tableView.indexPathForSelectedRow else { return }
self.tableView.beginUpdates()
self.dataSource[indexPath.section].rows.remove(at: indexPath.item)
if self.dataSource[indexPath.section].rows.isEmpty {
self.dataSource.remove(at: indexPath.item)
self.tableView.deleteSections(IndexSet(arrayLiteral: indexPath.section), with: .fade)
}
self.tableView.deleteRows(at: selectedRows, with: .fade)
self.tableView.endUpdates()
My dataSource object:
struct DataSource {
var section:String
var rows:[Row]
}
struct Row {
var data:String
}
The problem is when I select more than one row and try to delete selected rows I've got a crush with following message:
Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (5) must be equal to the number of rows contained in that section before the update (6), plus or minus the number of rows inserted or deleted from that section (0 inserted, 2 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
While I delete by one row my mechanism works fine, as expected. Even deletes an empty section. Any thoughts, where am I wrong? Thanks a lot.
Solution: just add inverted indexPath array. let invertedIndexPathes = selectedRows.sorted(by: >)
Fixed mechanism:
guard let selectedRows = self.tableView.indexPathsForSelectedRows,
let indexPath = self.tableView.indexPathForSelectedRow else { return }
let invertedIndexPathes = selectedRows.sorted(by: >)
self.tableView.beginUpdates()
for itemIndexPath in invertedIndexPathes {
self.dataSource[itemIndexPath.section].rows.remove(at: itemIndexPath.row)
self.tableView.deleteRows(at: [itemIndexPath], with: .fade)
self.tableView.reloadData()
}
if self.dataSource[indexPath.section].rows.isEmpty {
self.dataSource.remove(at: indexPath.item)
self.tableView.deleteSections(IndexSet(arrayLiteral: indexPath.section), with: .fade)
}
self.tableView.endUpdates()

NXException when removing and then adding an itme to UITableView

When I remove an object from a list and try to add a new one in I get this error
2020-01-24 14:40:26.692343+1300 HappyDays[25416:1017241] *** 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 (3) must be equal to the number of rows contained in that section before the update (0), 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).'
I see other issues similar to this but I've tried implementing those solutions . (Similar issue , another similar issue)
Sections of my code:
Selecting the cell to delete if from the table
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
activeObjectives.actives.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .left)
}
Adding a new object to the table by tapping a button
#IBAction func getGoals(_ sender: UIButton) {
let newRowIndex = activeObjectives.actives.count
activeObjectives.setRandomGoalToActive(allObjectiveList: allGoalsArray)
addActiveGoalToactiveObjectives()
let indexPath = IndexPath(row: newRowIndex, section: 0)
let indexPaths = [indexPath]
activeGoalDisplay.insertRows(at: indexPaths, with: .automatic)
}
In case it's also needed, here is my addActiveGoalToactiveObjectives function called in the above
func addActiveGoalToactiveObjectives() {
for goal in allGoalsArray.goalsList {
if goal.isActive == true && activeObjectives.actives.contains(goal) == false {
activeObjectives.actives.append(goal)
}
}
}
Thanks in advance, any help is greatly appreciated
I found the issue. I wasn't setting an object value to false when removing it from the list. Now when I remove them I set the object to inactive.
activeObjectives.actives[indexPath.row].setInactive()
activeObjectives.actives.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .left)
}```

Dispatch.main.asyncAfter() crash app when called before it's finished

so I have an app with radiobuttons to check off tasks, everything's working as expected as long as I let the animation finish but if I press two buttons at the same time I get an error:
libc++abi.dylib: terminating with uncaught exception of type NSException
The Code executed every time a radiobutton is tapped
func RadioTapped(_ cell: TableViewCell) {
if let indexPath = tableView.indexPath(for: cell) {
// Removes task from coreData
let task = self.tasks[indexPath.row]
print(tasks.count)
self.context.delete(task)
print(tasks.count)
(UIApplication.shared.delegate as! AppDelegate).saveContext()
do{
self.tasks = try self.context.fetch(TodayTask.fetchRequest())
// Animates the removal of task cell
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(800),execute: {
self.tableView.beginUpdates()
self.tableView.deleteRows(at: [indexPath], with: .fade)
self.tableView.endUpdates()
})
} catch {
print("Fetching Failed")
}
}
}
Error Message
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 (11) must be equal to the number of rows contained in that section before the update (13), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
Table row delete operation also requires to delete element of array of table.
According to your code, self.tasks may be an array for your table list.
Delete an element of 'self.tasks' from same indexes, for which you are deleting your rows.
Hint:
// Remove array element
self.tasks.remove(at: <index.row>)
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(800),execute: {
self.tableView.beginUpdates()
self.tableView.deleteRows(at: [indexPath], with: .fade)
self.tableView.endUpdates()
})

Insert new rows in tableView in iOS

I am writing an iOS app in Swift.
Whenever the page loads it gets the list of movies from server and it populates that list into tableView.
I wrote the code for getting JSON from server in a static library (Objective-C) and am receiving json to app via Notification design pattern.
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(ReceivedNListOfMoviesNotification(_:)), name: Notification.Name(VUSDK.basicNotificationName()), object: nil)
requestForData()
}
func ReceivedNListOfMoviesNotification(_ notification:NSNotification)
{
if let info = notification.userInfo {
basicArray=info["Search"] as! [Any]
if basicArray.count>0 {
tableView.beginUpdates()
self.tableView.insertRows(at: [IndexPath.init(row: self.basicArray.count-1, section: 0)], with: .automatic)
tableView.endUpdates()
}
}
}
But app is crashing:
*** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3600.7.47/UITableView.m:1737
2017-04-23 13:49:12.562 VUDemo[4835:164247] *** 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 (10) must be equal to the number of rows contained in that section before the update (0), 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).'
Replace
if basicArray.count>0 {
tableView.beginUpdates()
self.tableView.insertRows(at: [IndexPath.init(row: self.basicArray.count-1, section: 0)], with: .automatic)
tableView.endUpdates()
}
with
if !basicArray.isEmpty {
tableView.reloadData()
}
because you are overwriting the entire array rather than adding a single item.

Swift 3.0 Unable to delete a row from a UITableView

I'm using Xcode 8 and swift 3.
I'm getting an assertion failure when I try to delete a row from a UITableView.
Assertion failure in -[UITableView _endCellAnimationsWithContext:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3599.5/UITableView.m:1610
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 (25) must be equal to the number of rows contained in that section before the update (25), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
Code:
// create a cell for each table view row
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// create a new cell if needed or reuse an old one
let cell:UserCell = self.tableView.dequeueReusableCell(withIdentifier: "tblCell") as! UserCell!
cell.titleLabel.text = self.animals[(indexPath as NSIndexPath).row]
cell.btnDelete.addTarget(self, action:#selector(ViewController.buttonClicked(sender:)), for: UIControlEvents.touchUpInside);
return cell
}
func buttonClicked(sender:UIButton) {
if let superview = sender.superview {
if let cell = superview.superview as? UserCell {
if let indexPath = self.tableView.indexPath(for: cell){
print("row = ",indexPath.row)
self.tableView.beginUpdates()
self.tableView.deleteRows(at: [indexPath], with: .left)
self.tableView.endUpdates()
self.animals.remove(at:indexPath.row)
}
}
}
}
I have just started learning swift so please help me.
try to move self.animals.remove(at:indexPath.row) before self.tableView.endUpdates() and after self.tableView.beginUpdates() I think that might solve your problem.

Resources