How to move UITableViewCell back and forth to show it can be swiped?

I have a piece of code that I saw long time ago to animate a view. Since our UITableViewCell is also a view, we can use it :) You just need to get your visible cell to animate, like so:

if let visibleCell = self.tableView.cellForRow(at: IndexPath(row: 0, section: 0)) as? CustomCell {
        print("Started animation...")
        let animation = CAKeyframeAnimation(keyPath: "transform.translation.x")
        animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
        animation.duration = 0.6
        animation.values = [-20.0, 20.0, -20.0, 20.0, -10.0, 10.0, -5.0, 5.0, 0.0 ]
        visibleCell.layer.add(animation, forKey: "shake")
    }

Let me know if this helps. Tested it.

EDIT:

Animating your UITableView to let the user see that they can swipe on a cell is pretty easy, try it like so:

    DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1)) {
        self.tableView.setEditing(true, animated: true)
        DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1)) {
            self.tableView.setEditing(false, animated: true)
        }
    }

HOWEVER, if you want to swipe programmatically your cell to show your custom row actions, (I've been researching this for an hour), you can only achieve this, as far as I know, by using method swizzling. See this SO answer: http://codejaxy.com/q/186524/ios-swift-uitableview-how-to-present-uitableviewrowactions-from-pressing-a-button


Swift Solution

Well, about 1.5 years later I finally came up with a solution.

Step 1 - Cell UI Setup

I set up my custom table view cell like this: UI Work

  • A and B represent the swipe action colors.
  • C is the UIView that I will animate side-to-side.

Step 2 - Add Animation to Cell

func animateSwipeHint() {
    slideInFromRight()
}

private func slideInFromRight() {
    UIView.animate(withDuration: 0.5, delay: 0.3, options: [.curveEaseOut], animations: {
        self.cellBackgroundView.transform = CGAffineTransform(translationX: -self.swipeHintDistance, y: 0)
        self.cellBackgroundView.layer.cornerRadius = 10
    }) { (success) in
        UIView.animate(withDuration: 0.2, delay: 0, options: [.curveLinear], animations: {
            self.cellBackgroundView.transform = .identity
        }, completion: { (success) in
            // Slide from left if you have leading swipe actions
            self.slideInFromLeft()
        })
    }
}

private func slideInFromLeft() {
    UIView.animate(withDuration: 0.5, delay: 0, options: [.curveEaseOut], animations: {
        self.cellBackgroundView.transform = CGAffineTransform(translationX: self.swipeHintDistance, y: 0)
    }) { (success) in
        UIView.animate(withDuration: 0.2, delay: 0, options: [.curveLinear], animations: {
            self.cellBackgroundView.transform = .identity
        })
    }
}

Step 3 - Trigger the Animation

In the viewDidLoad of the view controller that has the table view, I have this code:

if self.tableView.visibleCells.count > 0 {
    let cell = self.tableView.visibleCells[0] as! TableViewCell
    cell.animateSwipeHint()
}

Example:

Example Animation

Video Solution

I created a video if you'd like a more in-depth walkthrough of this solution: https://youtu.be/oAGoFd_GrxE

Tags:

Ios

Swift