Hanyoup Cho
Hanyoup Cho

Reputation: 95

Deleting rows in TableViewController after Swiping them in TableViewCell

I'm building an app with CoreData, using UITableViewController.swift and UITableViewCell.swift.

I'm trying to delete a row as in Clear to-do app by using UIPanGestureRecognizer in UITableViewCell.swift. I'm able to pan rows to the left and the right, but I'm not sure how I can get an indexPath for those selected rows and delete them in UITableViewController.swift where all the data is located.

EduDicTableViewCell.swift:

override func awakeFromNib() {
    super.awakeFromNib()

    let recognizer = UIPanGestureRecognizer(target: self, action: #selector(EduDicTableViewCell.handlePan(_:)))

    recognizer.delegate = self
    addGestureRecognizer(recognizer)
}

//MARK: - horizontal pan gesture methods
func handlePan(recognizer: UIPanGestureRecognizer) {
    // 1
    if recognizer.state == .Began {
        // when the gesture begins, record the current center location
        originalCenter = center
    }
    // 2
    if recognizer.state == .Changed {
        let translation = recognizer.translationInView(self)
        center = CGPointMake(originalCenter.x + translation.x, originalCenter.y)
        // has the user dragged the item far enough to initiate a delete/complete?
        deleteOnDragRelease = frame.origin.x < -frame.size.width / 2.0
    }
    // 3
    if recognizer.state == .Ended {
        let originalFrame = CGRect(x: 0, y: frame.origin.y,
                                   width: bounds.size.width, height: bounds.size.height)
        if deleteOnDragRelease {
            print("send it")



        } else {
            UIView.animateWithDuration(0.2, animations: {self.frame = originalFrame})
            print("Bounced Back")
        }
    }
}

Thanks for reading!

Upvotes: 1

Views: 597

Answers (1)

pbasdf
pbasdf

Reputation: 21536

You could use a delegate/protocol in your custom cell, which calls a suitable method in the table view controller:

Add a protocol definition to the cell:

protocol EduDicTableViewCellDelegate {
    func didSwipeDelete(cell: UITableViewCell)
}

and then add an (optional) delegate variable with this protocol:

var delegate : EduDicTableViewCellDelegate? = nil

In the handlePan method, add a line to call the delegate method when the pan is released:

if deleteOnDragRelease {
    print("send it")
    self.delegate?.didSwipeDelete(self)
} else ...

Note that the didSwipeDelete method passes self - the cell which was swiped.

In the table view controller, add the method to delete the cell (using the tableView's indexPathForCell method to get the indexPath corresponding to the cell which was swiped):

func didSwipeDelete(cell: UITableViewCell) {
    if let indexPath = self.tableView.indexPathForCell(cell) {
        print("didSwipeDelete \(indexPath.section) - \(indexPath.row)")
        // remove the object at this indexPath from the data source
        // and delete the corresponding table view row
        ...
    }
}

Amend the class definition for the table view controller to indicate that it adopts the protocol:

class CustomTableViewController: UITableViewController, EduDicTableViewCellDelegate {
    ...
}

Finally, in the cellForRowAtIndexPath method, set the delegate variable on the cell to self (the table view controller):

cell.delegate = self

Upvotes: 1

Related Questions