This project is meant to demonstrate using the responder chain to delegate the actions of UIControl objects inside of a UITableViewCell. This also works with UICollectionViewCells, but this project will use UITableViewCells. This project is simply meant to demonstrate one approach to a common situation that iOS developers encounter.
Let's say we have a UITableVewCell
subclass called SomeCell
, which has a button. We want the view controller which owns the table view to be notified when the button inside SomeCell
is pressed.
- Create a delegate protocol
SomeCellDelegate
- Add a
delegate
property of typeSomeCellDelegate
to the cell - Make the cell the target of the button
- Inside of the button's target method, call the correct function on the delegate, usually passing the cell as an argument
- Make sure the view controller conforms to the delegate
This isn't necessarily bad, but there are some potential issues.
- You could easily have a retain cycle if the protocol isn't a class protocol, and the delegate property isn't weak
- You could also have to manually set the delegate of the cell
-
Create a delegate protocol
SomeCellDelegate
. Make sure that the protocol is marked with@objc
, because we need to use the Objective-C runtime -
Make the cell the target of the button
-
Inside of the button's target method, add this line:
UIApplication.shared.sendAction(#selector(SomeCellDelegate.doSuff(_:)), to: .none, from: self, for: .none)
-
Make sure the view controller conforms to the delegate
The sendAction
funtion will cause the system to go up the responder chain, and call resonds(to:)
on each responder, until the function returns true
. This solves the potential retain cycle issue, and is overall a more clean solution, using the responder chain as it is meant to be used.