简体   繁体   中英

ios is it possible for a uiscrollview to detect a single tap by a user while still providing its dragging, scrolling capabilities?

I currently am using a UIScrollView to work as a way of scrolling/ dragging the cursor/ marker of a graph that I am displaying on my app. I use scrollViewDidScroll, etc. to detect the contentoffset's position and manipulate what I display on the screen based on this position.

My question is if it is possible to also detect a user's single tap on the screen and get this tap's position (to then set the contentoffset to this position)?

I have read some tutorials that describe creating a subclass of a uiscrollview, but it seems like these subclasses will ONLY account for a single tap and not drags/scrolls also.

Does anyone have any insight on how I might be able to detect a user's single tap on my UIScrollView while still having its scrolling/ dragging capabilities?
Thank you in advance!

Use the following code for your scrollView object :

UITapGestureRecognizer *singleTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTap:)];
singleTapGestureRecognizer.numberOfTapsRequired = 1;
singleTapGestureRecognizer.enabled = YES;
singleTapGestureRecognizer.cancelsTouchesInView = NO;
[scrollView addGestureRecognizer:singleTapGestureRecognizer];
//[singleTapGestureRecognizer release]; Not needed in ARC-enabled Project

}

- (void)singleTap:(UITapGestureRecognizer *)gesture {  
//handle taps   
}

Swift 5

let scrollViewTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(scrollViewTapped(_:)))
scrollViewTapGestureRecognizer.numberOfTapsRequired = 1
scrollViewTapGestureRecognizer.isEnabled = true
scrollViewTapGestureRecognizer.cancelsTouchesInView = false
scrollView.addGestureRecognizer(scrollViewTapGestureRecognizer)

@objc func scrollViewTapped(_ sender: UITapGestureRecognizer) {
    print("UIScrollView was tapped.")
}

The first part of the question is pretty simple to get going. If you have a UIScrollView subclass, you can just add a touchesEnded override that looks like this:

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];

    if ([touch tapCount] == 1) {

        CGPoint location = [touch locationInView:self];

        [self setContentOffset:location animated:YES];

    }


}

In the case of the scroll view, the -locationInView for the touch will actually already have the ContentOffset added into it. What this code will do is scroll the scroll view so that the point the user touched is at the top-left of the view. This probably isn't what you want exactly, so you'll have to do things like add in an offset if you want the scroll to end up 10 pixels in, or you'd make another CGPoint with only the x value out of the location if your scroller isn't left-to-right.

This won't interfere with being able to actually do the scroll.

Have you looked into attaching UITapGestureRecognizer to the scrollView? I've attached a UITapGestureRecognizer to a UIScrollView and used –gestureRecognizerShouldBegin: and/or –gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer: to cancel the built in panning when a touch is desired.

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