uiscrollview 和 uibutton 对触摸事件透明
Posted
技术标签:
【中文标题】uiscrollview 和 uibutton 对触摸事件透明【英文标题】:uiscrollview and uibutton behaves transparent for touch events 【发布时间】:2011-12-15 00:15:59 【问题描述】:我有一个 UIView 的自定义子类和一个带有背景图像的全屏 UIButton,正如您在图像中看到的那样, 在右侧,有一个 UIView,上面有一个 UIImageView 和一些其他不重要的标签和按钮。重要的部分是,该 UIView 上有两个滚动视图,在运行时,我在启用垂直滚动的那些滚动视图上添加 UIButtons(不是小的,200 x 100)。 情况真的很复杂,所以我会把在不同条件下发生的事情写成项目。在我的应用程序中,有 10 个完整的屏幕,在 UIView 的自定义子类上,我使用 UIPanGestureRecognizer 从一个滚动到另一个。我有充分的理由不为此使用滚动视图。所有的窗口(下图,不是 UIWindow )都在循环中填充它们的内容,所以它们的运行代码完全相同,并且它们都是从同一个 .xib 文件创建的。最后一个信息,覆盖所有窗口的较大的 UIButton 有一个 touchupinside 动作,而滚动视图中的较小按钮有自己的 touchupinside 选择器。
我的一些窗口可以完美运行,如果我触摸屏幕上的任何位置,就会调用较大的按钮操作在滚动视图中,他们的动作被触发,最后我可以在这些按钮中完美滚动。 我的一些窗口,当我尝试滚动滚动视图时,较大的窗口 pangesturerecognizer 捕获此事件而不是小滚动视图,如果我触摸该滚动视图中的小按钮,则触发较大的按钮事件(它通过所有通过 uibutton > uiscrollview > uiimageview > uiview 到按钮处的 uibutton 就像它们不存在一样) 如果我将右侧容器视图替换为大 uibutton 上的某个其他位置,它会随机运行是否正常,有时其中一个滚动视图运行良好而另一个不运行。 它具有一致的行为,如果在一个位置上,它有效,它总是有效,如果不是,它永远不会。 同样,所有视图和子类都启用了它们的用户交互,是的,相反的情况已经不可能,因为行为仅根据大 uibutton 上的容器视图的位置而改变,并且也会根据大 uibuttons 背景图像而改变。 我放置了一个 touchesBegan 方法仅用于测试目的,当触摸没有按预期工作时,使用 touch.view 触发的事件是大按钮的容器,即使我触摸滚动视图中的一个小按钮.我已经为此花了两天时间,但没有结果。什么会导致这种行为?
编辑:在 krumelur 发表评论后,我将重点从这些视图的配置更改为我提供给容器视图的动画,我注意到问题出在动画上,我正在添加代码部分它为所有十个窗口设置动画,并且表现得像一个自定义滚动视图。所有窗口都有其自定义图层类,当我捕捉到手势识别器时,我使用以下代码在屏幕上移动窗口。该代码中的项目是一个包含所有窗口层的数组。动画导致了这种奇怪的情况,但我还想不通..
- (void)layoutSublayers
[super layoutSublayers];
[CATransaction begin];
[CATransaction setDisableActions:YES];
float angleDelta = 2 * M_PI / [items count];
float a = angle;
for (UIBaseLayer *l in items)
l.position = self.position;
CATransform3D translation = CATransform3DMakeTranslation(cosf(a)*(radius.x), 1.0, (sinf(a)*radius.y) - radius.y*1.0);
float dailyAngle = (M_PI_2 - a);
CATransform3D rotation = CATransform3DMakeRotation(dailyAngle, 0, 1.0, 0);
CATransform3D t = CATransform3DConcat(rotation, translation);
l.transform = t;
a += angleDelta;
[CATransaction commit];
http://img836.imageshack.us/img836/296/screenshot20111215at013.png
【问题讨论】:
我不想让你失望,但我想说你的问题太复杂了,而且信息太少,无法提供详尽的答案。有很多事情可能会出错,以至于无法说出问题所在。可能是错误连接的事件处理程序,您的视图的 z 顺序混淆,UIScrollView 的某些属性设置不正确。我建议调试的基础知识:简化它。把它分解。删除不必要的控件。重新考虑您的设计。重新开始。 【参考方案1】:bringSubviewToFront
在 5.0 上无法可靠运行(在 5.1 上不需要 hack)
我必须在按钮周围添加一个更大的透明 UIButton
,该按钮的行为就像它在 5.1 之前的 ios 上被禁用一样才能修复此问题。
【讨论】:
【参考方案2】:最后我发现,即使我用CATransform3DMakeTranslation
和layer.zPosition
设置发回视图,触摸事件也会根据它们的帧位置进入视图。目前甚至没有看到(被其他人覆盖)的视图仍然会吸引人。只需为当前屏幕上的视图编写一行代码 ([self.superview bringSubviewToFront:self]
) 即可解决问题。
为了对此进行测试并理解我在说什么,我制作了一个简单的测试应用程序,上面只有两个按钮。
蓝色和黄色按钮。蓝色按钮覆盖黄色按钮,因此您只能在开头看到蓝色按钮。
在修改蓝色按钮的内部代码时,我只需将其发送回buttons.layer.zPosition = -1
。在此之后,屏幕上不再有蓝色按钮的可见部分,而是我现在只看到黄色按钮,但是当我触摸黄色按钮(或者我认为我正在触摸它)时,仍然有蓝色按钮在代码运行中触摸。
我不确定这是否是理想的逻辑,但对我来说似乎不合理。
如上所述,写入[blueButton.superview sendSubviewToBack:blueButton]
同时将其层zPosition
设置为-1 可以正常工作。
【讨论】:
以上是关于uiscrollview 和 uibutton 对触摸事件透明的主要内容,如果未能解决你的问题,请参考以下文章
如何使 UIButton 与 UIScrollView 一起移动