I have a UIScrollView
with a child UIView
. I've gone ahead and added a UITapGestureRecognizer
to the child view like so:
// in child
- (void)setup
{
[self addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)]];
}
// and the handler
- (void)handleSingleTap:(UITapGestureRecognizer*)sender
{
if (sender.state == UIGestureRecognizerStateEnded)
NSLog(@"tap ended"); // this gets called
else if (sender.state == UIGestureRecognizerStateBegan)
NSLog(@"tap began"); // never get's called
}
This code could be in a view controller but I have reason to handle the touch in the view itself.
As you can see, I'm testing for the state of the tap. However the only state that get's called is when the user removes his finger from the screen, completing the tap. That is, UIGestureRecognizerStateEnded.
When the user taps on a child view (within the scrollView), I understand that the parent scroll view 'intercepts' all touches and decides if they are relevant (for panning, zooming, whatever...) and if not passes the touch(es) down to its subviews. Therefore touchesBegan:withEvent:
never gets called on the scrollview's subviews.
WHAT I WOULD LIKE is to detect a touch down event (that is, the instant the user places a finger on the screen), within the child view, regardless of whether the user then pans, scrolls, or taps, and handle that tap within the child. The scrollview's behaviour should be unchanged.
Perhaps there is a better approach sans gesture recognizers such as overriding hitTest:withEvent
but my puny human brain can't seem to figure it out!
UPDATE/EXAMPLE:
If you take a look at a UITableView
which is a scrollview containing cells. You'll notice that placing your finger on a cell immediately highlights it. Then the act of scrolling 'cancels' the tap. That is generally the idea.