Here's the full code of what should be written in the subclass of the scroll view.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if (self.dragging) {
[super touchesBegan:touches withEvent:event];
} else {
[self.superview touchesBegan:touches withEvent:event];
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
if (self.dragging) {
[super touchesMoved:touches withEvent:event];
} else {
if ([self.delegate isKindOfClass:[UITableViewCell class]]) {
[(UITableViewCell *)self.delegate touchesCancelled:touches withEvent:event];
}
[self.superview touchesMoved:touches withEvent:event];
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
if (self.dragging) {
[super touchesEnded:touches withEvent:event];
} else {
[self.superview touchesEnded:touches withEvent:event];
}
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
if (self.dragging) {
[super touchesCancelled:touches withEvent:event];
} else {
[self.superview touchesMoved:touches withEvent:event];
}
}
In the touchesMoved
there's some extra code based on a bug I was encountering. To start, if your self.delegate
is not the UITableViewCell
, than replace that property with a property to your cell.
The cell needs to retrieve the cancel touch event during movement to prevent the undesired results. It can be easily reproducible as follows.
- Highlight the cell (assuming the scroll view is over the whole cell, if not highlight the scroll view)
- While the cell is highlighted, drag the table view
- Select any other cell and now the previously highlighted cell will retrieve the
didSelectCell
state
Another point to mention is that order matters! If the self.delegate
is not called before the self.superview
then the highlighted state wont happen.