Detecting hits in UIScrollView while still letting

2019-04-17 06:00发布

Is there a simple way to detect if someone touched a UIScrollView without having to disable user interactions?.

I know this has been answered a few times before, but every answer I find is somebody wanting to detect hits in an image. I don't have an image. What I do have is a scroll view with a number of text fields embedded in it. They used to be inside a UIControl, from which I could detect a touchDown and call resignFirstResponder on all my textfields (for when the keyboard is up). But when they are in a UIScrollView, I can't seem to find a simple way to do this.

I don't really want to have to write code to do the scrolling myself, which is what I assume I have to do if I disable user interactions and grab the touchesBegan message. But I may be wrong. I'm still a little new at this, but this is the first time I haven't been able to figure out the answer by reading the code doc and googling ...

Thanks for any help,

J

3条回答
爷、活的狠高调
2楼-- · 2019-04-17 06:26

Ok, now I feel a little silly answering this myself. I'm sure the other suggested answer would have worked also, but I found something else while browsing in other topics which totally fixed this for me.

I added this to my viewDidLoad:

UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(backgroundTap:)];

[scrollView addGestureRecognizer: singleTap];

Where backgroundTap is

- (IBAction)backgroundTap:(id)sender

is the function I was originally calling from touchDown in UIControl to resign all keyboard firstResponders.

This works perfectly and adds very little code. And I DON'T have to disable user interactions! Yay!

Thanks all for your comments and help.

J

查看更多
太酷不给撩
3楼-- · 2019-04-17 06:32

Override touchesBegan, do your processing, and call the super implementation so that the scroll view still gets the message.

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    //call resignFirstResponder
    [super touchesBegan:touches withEvent:event];
}
查看更多
倾城 Initia
4楼-- · 2019-04-17 06:33

I fiddled with this for a while, and found that simple touchesBegan and touchesEnd type stuff didn't really work.

They don't work because because of the gestures. For example touchesEneded never fires when you swipe to scroll (at least not in the UIScrollView). So while you can detect when a touch event starts, you'll never know when it ends.

I wasn't real keen on including a gesture recognizer for simple stuff and discovered that you can find out about the state of the scrolling better from interacting with the UIScrollView directly.

And it's not that painful. Just add the protocol, then add the functions you need for detection.

In the view (class) that contains the UIScrolView, add the protocol, then added any the functions from here to your view (class).

Example:

// --------------------------------
// In the "h" file:
// --------------------------------
@interface myViewClass : UIViewController  <UIScrollViewDelegate> // <-- Adding the protocol here

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView;


// --------------------------------
// In the "m" file:
// --------------------------------
@implementation BlockerViewController
UIScrollView *scrollView;

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    NSLog(@"end decel");
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
    NSLog(@"end dragging");
}

// All of the available functions are here:
// https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIScrollViewDelegate_Protocol/Reference/UIScrollViewDelegate.html
查看更多
登录 后发表回答