简体   繁体   中英

UIScrollView touch down handled by subview

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.

Adding the gesture recognizer to the child view puts you at the mercy of the scroll view, and the events it decides to pass down after it has determined that the user does not intend to scroll. If it fits your needs, one easy fix might be to set:

tableView.delaysContentTouches = NO;

This will cause touch methods to be called immediately.

http://developer.apple.com/library/ios/#documentation/uikit/reference/UIScrollView_Class/Reference/UIScrollView.html

Your other option is to listen for gestures on the scroll view itself, and use hit testing to determine how the user is interacting with child views.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM