1

Deleting a row from tableview using beginupdates/endupdates instead of reloadData.

 viewTeachertblView.beginUpdates()
 let indexPath = NSIndexPath(forRow: sender.tag, inSection: 0)
 self.viewTeachertblView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.None)
 viewTeachertblView.endUpdates()

This method doesnot work as cellForRowAtIndexPath is not called and indexpath gets out of track while deleting.

Here is the full source code:

extension ViewController :UITableViewDataSource,UITableViewDelegate{

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return teacherObj.count
    }

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {

        return 1
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCellWithIdentifier("teacherCell", forIndexPath: indexPath) as! TeacherTblVIewCell
        print(teacherObj[indexPath.row].valueForKey("teacher_name") as? String)
        cell.teacherName?.text = teacherObj[indexPath.row].valueForKey("teacher_name") as? String
        cell.deleteBtn.tag = indexPath.row
        cell.deleteBtn.addTarget(self, action: "deleteThisTeacher:", forControlEvents: UIControlEvents.TouchUpInside)
        return cell

    }


    func deleteThisTeacher(sender:UIButton){

        print("delete this username")
        //first delete this user name from the coredata
        print(sender.tag)
        teacherObj.removeAtIndex(sender.tag)
       // self.viewTeachertblView.reloadData()
        viewTeachertblView.beginUpdates()
        let indexPath = NSIndexPath(forRow: sender.tag, inSection: 0)
        self.viewTeachertblView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.None)
        viewTeachertblView.endUpdates()


    }

}

How to delete tableview row the beginupates/endupdates instead of deleting object from the datasource and reloading tableview

Stidgeon
  • 2,673
  • 8
  • 20
  • 28
  • 1
    Setting the button's tag based on the cell's `indexPath` is not the proper solution in a table view with dynamic rows. There are far better ways to determine the row for the button when the button is tapped. – rmaddy Dec 11 '15 at 06:07
  • please can you suggest a bettter one? –  Dec 11 '15 at 06:08
  • 1
    See http://stackoverflow.com/a/27107160/1226963 for the proper solution. – rmaddy Dec 11 '15 at 06:09
  • thanks for the answer..but why http://stackoverflow.com/questions/14679930/update-tag-after-delete-of-row-in-tableview says cellForRowAtIndexPath is called with beginupdates/endupdates and mine doesnot –  Dec 11 '15 at 06:30
  • Create a delegate method in the cell class and call that once the button is pressed and you'll get which cell was pressed and therefore the indexpath. – Bhavuk Jain Dec 11 '15 at 13:20

2 Answers2

1

Try this

    func deleteThisTeacher(sender:UIButton){
         let point = viewTeachertblView.convertPoint(CGPointZero, fromView: sender)
         if let indexPath = viewTeachertblView.indexPathForRowAtPoint(point) {
            teacherObj.removeAtIndex(indexPath.row)
            viewTeachertblView.beginUpdates()
            self.viewTeachertblView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.None)
            viewTeachertblView.endUpdates()
         }
    }
Kiran Ruth R
  • 902
  • 1
  • 11
  • 28
  • whats the beneit of wrapping that delete code at beginUpdates() and endupdates? –  Dec 11 '15 at 06:31
  • so that specific animations can be done to the row .Refer https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableView_Class/#//apple_ref/occ/instm/UITableView/beginUpdates and https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableView_Class/#//apple_ref/occ/instm/UITableView/endUpdates for details. – Kiran Ruth R Dec 11 '15 at 06:33
  • deleteRowsAtIndexPaths it does the job..no need that block for the animation –  Dec 11 '15 at 06:35
  • When this method is called in an animation block defined by the beginUpdates and endUpdates methods, UITableView defers any insertions of rows or sections until after it has handled the deletions of rows or sections. Thats why you need beginUpdates and endUpdates – Kiran Ruth R Dec 11 '15 at 06:37
  • if let touch = event.touchesForView(sender)?.first { let point = touch.locationInView(viewTeachertblView) if let indexPath = viewTeachertblView.indexPathForRowAtPoint(point) { print(indexPath.row) teacherObj.removeAtIndex(indexPath.row) self.viewTeachertblView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.None) } } just this does the job....and really was that worth? –  Dec 11 '15 at 06:38
0

As rmaddy told this does the job

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCellWithIdentifier("teacherCell", forIndexPath: indexPath) as! TeacherTblVIewCell
        print(teacherObj[indexPath.row].valueForKey("teacher_name") as? String)
        cell.teacherName?.text = teacherObj[indexPath.row].valueForKey("teacher_name") as? String
        cell.deleteBtn.addTarget(self, action: "deleteThisTeacher:event:", forControlEvents: UIControlEvents.TouchUpInside)

        return cell

    }

    func deleteThisTeacher(sender:UIButton, event: UIEvent){

        print("delete this username")
        //first delete this user name from the coredata
        print(sender.tag)

        if let touch = event.touchesForView(sender)?.first  {
            let point = touch.locationInView(viewTeachertblView)
            if let indexPath = viewTeachertblView.indexPathForRowAtPoint(point) {

                print(indexPath.row)
                 teacherObj.removeAtIndex(indexPath.row)
                 self.viewTeachertblView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.None)
            }
        }

    }