Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how does UIGestureRecognizer works with UIResponder chain?

I know that touch events can delivery to hit-view or gesture. but something confused me in my demo:

I have two subviews in my root view, one is testView (subclass of UIView), the other is testBtn(UIButton) which action is "testBtnClicked". Then, I add an UITapGestureRecognizer to my root view and set its action to "tapAction".

The problem comes:

when I touch on root view , it trigger "touchsBegan:withEvent:" 、 "tapAction" and "touchsCancelled:withEvent" method. That's what I expected;

When I touch on testView, it works the same as above;

when I touch on testBtn, it only triggered "testBtnClicked" method.Why?

why the gesture is recognized when I touch on testView not the root view? and why it's not recognized when I touch on testBtn?

like image 388
foolishBoy Avatar asked Dec 12 '16 09:12

foolishBoy


1 Answers

Aha! May be I got the answer:

Firstly, gestureRecognizers get the first opportunity to recognize a touch,as the App Doc says:

A window delays the delivery of touch objects to the view so that the gesture recognizer can analyze the touch first. During the delay, if the gesture recognizer recognizes a touch gesture, then the window never delivers the touch object to the view, and also cancels any touch objects it previously sent to the view that were part of that recognized sequence.

Secondly,In iOS 6.0 and later,UIButton actions prevent overlapping gesture recognizer behavior, also as the Apple Doc says:

In iOS 6.0 and later, default control actions prevent overlapping gesture recognizer behavior. For example, the default action for a button is a single tap. If you have a single tap gesture recognizer attached to a button’s parent view, and the user taps the button, then the button’s action method receives the touch event instead of the gesture recognizer. This applies only to gesture recognition that overlaps the default action for a control, which includes:

  • A single finger single tap on a UIButton, UISwitch, UIStepper, UISegmentedControl, and UIPageControl.
  • A single finger swipe on the knob of a UISlider, in a direction parallel to the slider.
  • A single finger pan gesture on the knob of a UISwitch, in a direction parallel to the switch.

If you have a custom subclass of one of these controls and you want to change the default action, attach a gesture recognizer directly to the control instead of to the parent view. Then, the gesture recognizer receives the touch event first. As always, be sure to read the iOS Human Interface Guidelines to ensure that your app offers an intuitive user experience, especially when overriding the default behavior of a standard control.

like image 187
foolishBoy Avatar answered Oct 07 '22 01:10

foolishBoy