Swift: Using Protocols to Add Custom Behavior to a UITableViewCell

Avery Pierce
2 min readDec 19, 2016

--

Out-of-the-box, UITableViewCells are fairly limited. The handful of standard styles don’t offer more than a couple labels and an image view. What if you wanted your cell to contain custom buttons and controls? At best, you can hook into the detail disclosure button, and possibly override appearance of it, but this is a bit of a hack. It’s typically better to build your own subclass and design your table view with your own subviews and buttons.

This is a good start. Now we would like our controller to hook into those two buttons. You might be tempted to add custom target-action pairs to each button during the cell configuration step of your table view’s data source. This is perilous for two reasons:

  1. If you aren’t careful, you could accidentally add the target-action pair multiple times as a cell is reused.
  2. It’s not easy to capture the index path of the cell whose button is tapped (traversing the view hierarchy to get to the cell itself is a bit sloppy, and the tag property of UIView isn’t ideal for complex table views)

A Swifty Approach: Protocols

Apple describes Swift a protocol-oriented language, so let’s try a protocol-oriented solution!

Create a custom delegate-style protocol for your cell class. I called mine SwiftyTableViewCellDelegate. For delegate-style protocols, you want the delegate’s user to have a weak reference to the delegate object. Since weak references can only be used on classes, our protocol will have to declare “class” conformance.

Add a delegate method for each action you want to track. In my example, I have a heart button and a trash button. I want to know when either of these buttons are tapped, so I create a delegate function for each of them.

Add a delegate property to your custom cell class. Make it weak and optional. Then, wire up the button actions to methods within the cell to call these delegate methods. This can be done in your storyboard.

integrating our custom delegate

Make your UITableViewController conform to the protocol you just setup. Also make sure to set the cell’s delegate to the controller itself.

The end result doesn’t look *that* much different than our original target-action based approach, but it solves both of our main problems!

  1. Since a cell only has one delegate, the table view controller can assign itself as the cell’s delegate each time the cell is used, and there’s no risk of over-listening.
  2. Since the delegate functions send the cell itself in the sender parameter, we can ask our table view to look up the index path very efficiently.

Wonderful!

--

--