在滚动时通过UIScrollView的子视图处理点击事件

时间:2012-07-24 11:25:26

标签: objective-c ios cocoa-touch uiscrollview uigesturerecognizer

我有自定义的UIScrollView子类,里面有一些内容视图。在其中一些我有UITapGestureRecogniser。滚动视图不滚动时,一切正常。但是当它滚动内容视图时,不会收到点按动作。在滚动视图滚动时,通过子视图处理点击操作的最简单的解决方案是什么?

详细信息:

MyScrollView水平滚动。它包含许多内容视图(例如MyContentView)。每个MyContentView的宽度约为MyScrollView宽度的三分之一。因此,目前大约有3-4个可见的MyContentView元素。 MyScrollView的主要行为是1)确保在滚动MyContentView个元素后,其中一个元素位于屏幕中心, 2)滚动到MyContentView的中心,如果用户点击它。因此,我希望得到的主要答案是如何在MyContentView正在减速的过程中“正确”实施MyScrollView中的点击操作处理。

我发现了一些相同的问题和答案,但没有一个人满意我。最好的方法是实现UITapGestureRecogniser委托的gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:。但在这种情况下,我有时候(当我点击时,做出轻微的拖拽和释放手指,因此水龙头是钢可识别的(让我们称之为 quasi tap ))同时有点击和滚动事件,它会导致我的错误即使滚动视图在我开始点击时没有滚动也是如此。当用户进行准点击时,我的应用程序会尝试滚动到点击的MyContentView元素,而不是立即处理正常滚动。它似乎更加可怕,因为在处理tap之后开始执行一些其他功能(在正常滚动时它不能执行)。

我需要解决方案,其中滚动视图等待足以确定它不是点击事件,然后才进行滚动。否则,如果已识别出点击事件,则不得发生滚动。

2 个答案:

答案 0 :(得分:5)

您也可以使用 @protocol 来使用自定义委托方法。在添加了UIScrollView的视图控制器中实现这些委托方法。

喜欢 MyContentView

在touchesBegan方法中,

[self.delegate contentViewTapped:self];

现在,在添加滚动视图的 ContainerView 类中,实现该方法:

 - (void)contentViewTapped:(MyContentView *)myContentView {

NSLog (@"ContentView no: %d", myContentView.tag); // if tag has been set while adding this view to scrollview.
}

浏览 @protocol

的示例

希望这是你所需要的。

享受编码:)

答案 1 :(得分:4)

这内置于UIScrollView - 请查看delaysContentTouchescanCancelContentTouches属性。这样可以在点击后拖动一小部分时缓解问题。

这是所有系统内置行为。我建议坚持使用Apple提供的界面感觉(例如它如何对小版本做出反应),这样你的应用就不会觉得用户的手机不合适了。

修改

或者,您可以禁用在手势识别器中滚动滚动视图,并在结束/取消后重新启用它。

进一步编辑: 我不明白 - 我已经创建了一个sample project,它说明了如何使用手势识别器委托方法拦截滚动视图的子视图中的触摸。请密切关注滚动视图的“可取消内容触摸”和“延迟内容触摸”属性。由于非常重要的原因,它们都是YES

滚动视图应该延迟内容触摸,直到确定用户是在尝试点按,伪点击(如你所说),还是平移滚动视图。 Apple已经编写了您正在尝试构建的功能; UIScrollView已经做了你想做的事。

问题是当滚动视图滚动时,系统不希望滚动视图的子视图拦截点击事件。为此,如果确定用户实际上正在尝试平移,则取消触摸事件。设置“延迟内容触摸”可启用此行为。确保它已打开,你应该没事。