ios 检测 UIScrollView 和 UIView 组件上的触摸事件 [放置在 UIScrollView 内]

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12243963/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 19:58:17  来源:igfitidea点击:

Detect touch event on UIScrollView AND on UIView's components [which is placed inside UIScrollView]

iosuiscrollviewuitapgesturerecognizer

提问by uerceg

I have UIViewController on my simple storyboard IPad project which contains UIScrollView which is placed over entire surface (1024 x 768). I have created 3 XIB files which are UIViews which my application loads on start in viewDidLoad and add them into UIScrollView. Each of these 3 XIB files contains only one UIButton.

我在我的简单故事板 iPad 项目上有 UIViewController,其中包含放置在整个表面 (1024 x 768) 上的 UIScrollView。我创建了 3 个 XIB 文件,它们是我的应用程序在 viewDidLoad 中启动时加载的 UIViews,并将它们添加到 UIScrollView 中。这 3 个 XIB 文件中的每一个都只包含一个 UIButton。

This is hierarchy:

这是层次结构:

~ UIViewController (UIViewControllerClassis class for this UIViewController)

~~ UIScrollView (contains 3 identical UIViews)

~~~ UIView (UIViewClassis File's Owner for this XIB file)

~~~~ UIButton

~ UIViewController ( UIViewControllerClass是这个 UIViewController 的类)

~~ UIScrollView(包含 3 个相同的 UIView)

~~~ UIView (UIViewClass是此 XIB 文件的文件所有者)

~~~~ UIButton

I would like that my UIViewControllerClass becomes aware of both: touch anywhere on UIScrollView component AND if UIScrollView is touched, if UIButton inside of UIView in UIScrollView is touched, to have information that exactly that button is touched.

我希望我的 UIViewControllerClass 能够同时知道:触摸 UIScrollView 组件上的任何地方,如果触摸 UIScrollView,如果触摸 UIScrollView 中的 UIView 内部的 UIButton,以获取确切触摸该按钮的信息。

I made IBAction inside UIViewClass for touch on UIButton inside UIView in UIScrollView and when I set User Interaction Enabled = YES on all elements (UIViewController, UIView and UIScrollView) this method is called as it should.

我在 UIViewClass 中创建了 IBAction,用于在 UIScrollView 中的 UIView 中触摸 UIButton,并且当我在所有元素(UIViewController、UIView 和 UIScrollView)上设置 User Interaction Enabled = YES 时,该方法将被调用。

But at this point my UIViewControllerClass isn't aware that touch occurred inside UIScrollView on that UIButton. I made touch recognizer like this:

但此时我的 UIViewControllerClass 不知道在 UIButton 上的 UIScrollView 内部发生了触摸。我制作了这样的触摸识别器:

UITapGestureRecognizer *touch = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTouch)];
touch.numberOfTouchesRequired = 1;

and added it to UIScrollView component. In this way I am able to detect touch event on UIScrollView component in UIViewControllerClass, but touch event handler for UIButton in UIView which is inside UIScrollView isn't called anymore.

并将其添加到 UIScrollView 组件。通过这种方式,我能够检测到 UIViewControllerClass 中 UIScrollView 组件上的触摸事件,但是不再调用 UIScrollView 中 UIView 中 UIButton 的触摸事件处理程序。

So, I need to have these two informations in UIViewControllerClass:

所以,我需要在 UIViewControllerClass 中有这两个信息:

  • Touch on UIScrollView component was made
  • Touch on UIButton in UIView which is inside UIScrollView (if this button was touched) was made
  • 触摸 UIScrollView 组件
  • 在 UIScrollView 内的 UIView 上触摸 UIButton(如果触摸了这个按钮)

I suppose that attaching touch event recognizer to entire UIScrollView component isn't solution, since it disables all touch event handlers I wrote inside UIViewClass.

我想将触摸事件识别器附加到整个 UIScrollView 组件不是解决方案,因为它禁用了我在 UIViewClass 中编写的所有触摸事件处理程序。

I think solution is that somehow touches which are made on components in UIView inside UIScrollView should be sent up to UIViewControllerClass, but I didn't found a way to do this.

我认为解决方案是以某种方式在 UIScrollView 内的 UIView 组件上进行的触摸应该发送到 UIViewControllerClass,但我没有找到一种方法来做到这一点。

If anyone can help me, I'd be very grateful. Thanks in advance.

如果有人可以帮助我,我将不胜感激。提前致谢。



[edit #1: ANSWER by Zheng]

[编辑#1:郑的回答]

Tap gesture must have cancelsTouchesInViewoption set to NO!

点击手势必须将cancelsTouchesInView选项设置为NO

For my case above, this line solves everything:

对于我上面的情况,这条线解决了所有问题:

touch.cancelsTouchesInView = NO;

Many thanks to Zheng.

非常感谢郑。

回答by Zhang

I don't know if this works for you or not, but I've given an answer about touch events for views inside scrollview here:

我不知道这是否适合你,但我已经在这里给出了关于滚动视图内部视图的触摸事件的答案:

Dismissing the keyboard in a UIScrollView

在 UIScrollView 中关闭键盘

The idea is to tell the scrollView not to swallow up all tap gestures within the scroll view area.

这个想法是告诉 scrollView 不要吞下滚动视图区域内的所有点击手势。

I'll paste the code here anyways, hopefully it fixes your problem:

无论如何,我都会在这里粘贴代码,希望它可以解决您的问题:

UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideKeyboard)];

// prevents the scroll view from swallowing up the touch event of child buttons
tapGesture.cancelsTouchesInView = NO;    

[pageScrollView addGestureRecognizer:tapGesture];

[tapGesture release];

...

// method to hide keyboard when user taps on a scrollview
-(void)hideKeyboard
{
    [myTextFieldInScrollView resignFirstResponder];
}

回答by Guillaume

You can subclass your UIScrollView and override the method - hitTest:withEvent:which is called by the system to determine which view will handle the event. Whenever it is called, you can assume that a touch event occurred inside the scroll view, and by calling the super implementation, you can get the view which would normally process the event.

您可以将 UIScrollView 子类化并覆盖- hitTest:withEvent:系统调用的方法,以确定哪个视图将处理事件。每当它被调用时,您可以假设滚动视图内部发生了触摸事件,并且通过调用超级实现,您可以获得通常处理该事件的视图。

回答by Aks

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。还为您的子视图提供一些标签编号以区分选择器。& 还使他们的用户交互为真。

let tap = UITapGestureRecognizer(target: self, action:

selector(didTapByUser(_:)))

让 tap = UITapGestureRecognizer(target: self, action:

选择器(didTapByUser(_:)))