Search code examples
swiftanimationuitableviewrowaction

UITableViewRowAction completion after animation


In my table, I have an UITableViewRowAction for editActionsForRowAtIndexPath. When I press it, it will delete all the data in my array, resulting in triggering the didSet on the array ending with the view changing. The code looks as follows:

var data: [Int] = [Int]() {
    didSet {
        if data.isEmpty {
            // change view
        }
    }
}

func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]? {
    var confirm = UITableViewRowAction(style: .Default, title: "Confirm") { (action: UITableViewRowAction!, indexPath: NSIndexPath!) -> Void in
        self.data.removeAll(keepCapacity: false)
        self.tableView.setEditing(false, animated: true)
    }
    return [confirm]
}

What I'd like to get is some kind of completion after the animation of the UITableViewRowAction is finished (row moving back in it's place), then empty the array and changing the views. If possible I'd like to avoid using a manual delay.


Solution

  • Try this code:

    var data: [Int] = [Int]() {
        didSet {
            if data.isEmpty {
                // change view
            }
        }
    }
    
    func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]? {
        var confirm = UITableViewRowAction(style: .Default, title: "Confirm") { (action: UITableViewRowAction!, indexPath: NSIndexPath!) -> Void in
            CATransaction.begin()
            CATransaction.setCompletionBlock({
                self.data.removeAll(keepCapacity: false)
            })
            self.tableView.setEditing(false, animated: true)
            CATransaction.commit()
        }
        return [confirm]
    }
    

    The code in CATransaction.setCompletionBlock({/* completion code */}) is run after the other code between CATransaction.begin() and CATransaction.commit() finishes getting executed. So here self.data.removeAll(keepCapacity: false) should get called after self.tableView.setEditing(false, animated: true) is finished animating.

    Hope this helps!

    NOTE: I have not tested this code myself with tableView.setEditing(...), but I have used it for tableView.deleteRowsAtIndexPaths(...).