In this episode we fix the problem of a scroll view blocking touches to a UITableViewCell by forwarding touch events from the scroll view and onto a delegate, which manages the cell's highlighted state properly.
Errata In the episode I create a strong reference to the tableView from a cell. In this way, I unintentionally create a retain cycle. Since UITableView retains its cells, a weak pointer is appropriate here. Thanks to Scott Williams for pointing this out. Episode Links Episode Source Code Catching Taps in a Scroll View Here we subclass UIScrollView into our own class, BSTapScrollView. It implements these methods: - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [super touchesBegan:touches withEvent:event]; if (!self.dragging) { [self.tapDelegate tapScrollView:self touchesBegan:touches withEvent:event]; } } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { [super touchesMoved:touches withEvent:event]; [self.tapDelegate tapScrollView:self touchesCancelled:touches withEvent:event]; } - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { [super touchesCancelled:touches withEvent:event]; [self.tapDelegate tapScrollView:self touchesCancelled:touches withEvent:event]; } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { NSLog(@"Touch on scroll view ended"); if (!self.dragging) { [self.tapDelegate tapScrollView:self touchesEnded:touches withEvent:event]; } else { [super touchesEnded:touches withEvent:event]; } } Note the use of a delegate that handles the tap events. The delegate is defined as: @protocol BSTapScrollViewDelegate <NSObject> @optional - (void)tapScrollView:(BSTapScrollView *)scrollView touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; - (void)tapScrollView:(BSTapScrollView *)scrollView touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event; - (void)tapScrollView:(BSTapScrollView *)scrollView touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event; @end To get this to work, we'll set our cell up as the tapDelegate for our scroll view: @interface MailMessageCell () <BSTapScrollViewDelegate> ... And in awakeFromNib... self.scrollView.tapDelegate = self; Managing the Highlighted State #pragma mark - BSTapScrollViewDelegate - (void)tapScrollView:(BSTapScrollView *)scrollView touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { NSLog(@"Setting highlighted..."); if (_isOpen) { } else { [self setHighlighted:YES animated:YES]; } } - (void)tapScrollView:(BSTapScrollView *)scrollView touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { NSLog(@"Setting normal..."); [self setHighlighted:NO animated:NO]; } - (void)tapScrollView:(BSTapScrollView *)scrollView touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { if (_isOpen) { return; } NSLog(@"did select...."); NSIndexPath *indexPath = [self.tableView indexPathForCell:self]; [self setHighlighted:NO animated:NO]; [self.tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone]; [self.tableView.delegate tableView:self.tableView didSelectRowAtIndexPath:indexPath]; [[NSNotificationCenter defaultCenter] postNotificationName:RevealCellDidOpenNotification object:self]; }