滚动视图手势识别器吃所有的触摸事件

时间:2022-01-07 08:14:59

I have a UIScrollView to which I added a single tap gesture recognizer to show/hide some UI overlay using:

我有一个UIScrollView,我添加了一个点击手势识别器来显示/隐藏一些UI覆盖:

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

and:

和:

- (void)handleTap:(UITapGestureRecognizer *)sender {
    // report click to UI changer
}

I added an easy table view to the bottom of the UIScrollView. Everything works right (scrolling both horizontally and vertically) but the problem is that taps are recognized only by the gesture recognizer (above), but not by the easy table view. If I remove The line that registers the gesture listener, everything works fine, the table view notices taps on itself.

我在UIScrollView的底部添加了一个简单的表格视图。所有操作都是正确的(水平和垂直滚动),但问题是,轻击只能由手势识别器识别(如上),而不能通过easy table视图识别。如果我删除了注册手势监听器的行,一切都很正常,表视图会注意到它自己被监听。

It's as if the gesture recognizer function "eats" the tap events on the table view and doesn't propagate them downward.

就好像手势识别器函数“吃”了表视图上的tap事件而没有向下传播。

Any help is appreciated

任何帮助都是赞赏

8 个解决方案

#1


66  

This should solve your problem.
Detect touch event on UIScrollView AND on UIView's components [which is placed inside UIScrollView]
The idea is to tell the gesture recognizer to not swallow up the touch events. To do this you need to set singleTap's cancelsTouchesInView property to NO, which is YES by default.

这应该能解决你的问题。检测UIScrollView上的触摸事件和UIView的组件(放在UIScrollView内)的想法是告诉手势识别器不要吞掉触摸事件。为此,您需要将singleTap的cancelsTouchesInView属性设置为NO,默认为YES。

UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
singleTap.cancelsTouchesInView = NO;
[scrollView addGestureRecognizer:singleTap]; 

#2


7  

Swift 3.0

斯威夫特3.0

 let singleTap = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
 singleTap.cancelsTouchesInView = false
 singleTap.numberOfTapsRequired = 1
 scrollView.addGestureRecognizer(singleTap)

And the selector method be like.

选择器方法是这样的。

func handleTap(_ recognizer: UITapGestureRecognizer) {
  // Perform operation
}

#3


6  

You can set which objects are to be included/excluded for touches.

您可以设置哪些对象将被包含/排除为触摸。

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gesture shouldReceiveTouch:(UITouch *)touch {            
   if (touch.view == [self view]) {
       return YES;
   }
   return NO;
}

#4


5  

I think the reason is that User Interaction Enabled is set to false for UIImageView. You should set it to true to enable tapping in it

我认为原因是用户交互被设置为false。您应该将其设置为true,以启用在其中进行敲打

#5


2  

Thanks @zambrey

由于@zambrey

Swift 2.2+ Version:

斯威夫特2.2 +版本:

scrollView.delegate = self

let allowMultipleTouches = UITapGestureRecognizer(target: self, action: #selector(genderPressed))
allowMultipleTouches.numberOfTapsRequired = 1
allowMultipleTouches.cancelsTouchesInView = false

scrollView.addGestureRecognizer(allowMultipleTouches)

If your scroll view is in the Storyboard, don't forget to pin the Outlet in the view controller. In this example, scrollView is the Outlet of the UIScrollView.

如果您的滚动视图在故事板中,不要忘记将Outlet固定在视图控制器中。在本例中,scrollView是UIScrollView的输出。

#6


2  

This worked for me in Swift 3 / Xcode 8

这对我来说很有效,3 / Xcode 8。

    self.scrollView.touchesShouldCancel(in: ** the view you want the touches in **)
    self.scrollView.canCancelContentTouches = false

Good luck!

好运!

#7


1  

TapGestures worked for me. The swipe on the other hand, I had to disable the scrolling and it worked.

TapGestures为我工作。另一方面,我不得不禁用滚动条,这样就可以了。

     swipeLeftGesture = UISwipeGestureRecognizer(target: self, action: #selector(swipeToNewImage(_:)))
     swipeLeftGesture.direction = .left
     scrollView.addGestureRecognizer(swipeLeftGesture)

     swipeRightGesture = UISwipeGestureRecognizer(target: self, action: #selector(swipeToNewImage(_:)))
     scrollView.addGestureRecognizer(swipeRightGesture)

    scrollView.isScrollEnabled = false

#8


1  

You can capture any kind of gestures in the UIscrollView. Make sure you also handle some of the default properties as well like set cancelsTouchesInView property to false, it is true by default. Also give some tag nos to your sub views to distinguish in selectors. & also enable their User interaction to true.

您可以在UIscrollView中捕获任何类型的手势。请确保您也处理了一些默认属性,比如设置cancelsTouchesInView属性为false,它在默认情况下为true。还要给子视图一些标记nos,以便在选择器中进行区分。&也使他们的用户交互变为真实。

let tap = UITapGestureRecognizer(target: self, action:

让tap = uitapgesturerecnizer(目标:自我,行动:

selector(didTapByUser(_:)))

#1


66  

This should solve your problem.
Detect touch event on UIScrollView AND on UIView's components [which is placed inside UIScrollView]
The idea is to tell the gesture recognizer to not swallow up the touch events. To do this you need to set singleTap's cancelsTouchesInView property to NO, which is YES by default.

这应该能解决你的问题。检测UIScrollView上的触摸事件和UIView的组件(放在UIScrollView内)的想法是告诉手势识别器不要吞掉触摸事件。为此,您需要将singleTap的cancelsTouchesInView属性设置为NO,默认为YES。

UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
singleTap.cancelsTouchesInView = NO;
[scrollView addGestureRecognizer:singleTap]; 

#2


7  

Swift 3.0

斯威夫特3.0

 let singleTap = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
 singleTap.cancelsTouchesInView = false
 singleTap.numberOfTapsRequired = 1
 scrollView.addGestureRecognizer(singleTap)

And the selector method be like.

选择器方法是这样的。

func handleTap(_ recognizer: UITapGestureRecognizer) {
  // Perform operation
}

#3


6  

You can set which objects are to be included/excluded for touches.

您可以设置哪些对象将被包含/排除为触摸。

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gesture shouldReceiveTouch:(UITouch *)touch {            
   if (touch.view == [self view]) {
       return YES;
   }
   return NO;
}

#4


5  

I think the reason is that User Interaction Enabled is set to false for UIImageView. You should set it to true to enable tapping in it

我认为原因是用户交互被设置为false。您应该将其设置为true,以启用在其中进行敲打

#5


2  

Thanks @zambrey

由于@zambrey

Swift 2.2+ Version:

斯威夫特2.2 +版本:

scrollView.delegate = self

let allowMultipleTouches = UITapGestureRecognizer(target: self, action: #selector(genderPressed))
allowMultipleTouches.numberOfTapsRequired = 1
allowMultipleTouches.cancelsTouchesInView = false

scrollView.addGestureRecognizer(allowMultipleTouches)

If your scroll view is in the Storyboard, don't forget to pin the Outlet in the view controller. In this example, scrollView is the Outlet of the UIScrollView.

如果您的滚动视图在故事板中,不要忘记将Outlet固定在视图控制器中。在本例中,scrollView是UIScrollView的输出。

#6


2  

This worked for me in Swift 3 / Xcode 8

这对我来说很有效,3 / Xcode 8。

    self.scrollView.touchesShouldCancel(in: ** the view you want the touches in **)
    self.scrollView.canCancelContentTouches = false

Good luck!

好运!

#7


1  

TapGestures worked for me. The swipe on the other hand, I had to disable the scrolling and it worked.

TapGestures为我工作。另一方面,我不得不禁用滚动条,这样就可以了。

     swipeLeftGesture = UISwipeGestureRecognizer(target: self, action: #selector(swipeToNewImage(_:)))
     swipeLeftGesture.direction = .left
     scrollView.addGestureRecognizer(swipeLeftGesture)

     swipeRightGesture = UISwipeGestureRecognizer(target: self, action: #selector(swipeToNewImage(_:)))
     scrollView.addGestureRecognizer(swipeRightGesture)

    scrollView.isScrollEnabled = false

#8


1  

You can capture any kind of gestures in the UIscrollView. Make sure you also handle some of the default properties as well like set cancelsTouchesInView property to false, it is true by default. Also give some tag nos to your sub views to distinguish in selectors. & also enable their User interaction to true.

您可以在UIscrollView中捕获任何类型的手势。请确保您也处理了一些默认属性,比如设置cancelsTouchesInView属性为false,它在默认情况下为true。还要给子视图一些标记nos,以便在选择器中进行区分。&也使他们的用户交互变为真实。

let tap = UITapGestureRecognizer(target: self, action:

让tap = uitapgesturerecnizer(目标:自我,行动:

selector(didTapByUser(_:)))