Cocoa touch uiscrollview和uibutton对于触摸事件的行为是透明的

Cocoa touch uiscrollview和uibutton对于触摸事件的行为是透明的,cocoa-touch,uiscrollview,uibutton,Cocoa Touch,Uiscrollview,Uibutton,我有一个自定义的UIView子类和一个全屏UIButton,上面有一个背景图像,如图所示, 在右侧,有一个UIView,上面有一个UIImageView和一些其他不重要的标签和按钮。重要的是,该UIView上有两个滚动视图,在运行时,我在那些启用垂直滚动的滚动视图上添加UIButtons(不是小的,200 x 100)。 情况真的很复杂,所以我将把在不同条件下发生的事情写下来。在我的应用程序中,在UIView的自定义子类上有10个完整的屏幕,我使用UIPangestureRecognitor从一

我有一个自定义的UIView子类和一个全屏UIButton,上面有一个背景图像,如图所示, 在右侧,有一个UIView,上面有一个UIImageView和一些其他不重要的标签和按钮。重要的是,该UIView上有两个滚动视图,在运行时,我在那些启用垂直滚动的滚动视图上添加UIButtons(不是小的,200 x 100)。 情况真的很复杂,所以我将把在不同条件下发生的事情写下来。在我的应用程序中,在UIView的自定义子类上有10个完整的屏幕,我使用UIPangestureRecognitor从一个屏幕滚动到另一个屏幕。我有一个很好的理由不使用scrollview。所有窗口(下图,不是UIWindow)都在一个循环中填充其内容,因此所有窗口的运行代码都完全相同,并且所有窗口都是从相同的.xib文件创建的。最后一个信息是,覆盖所有窗口的较大的UIButton有一个touchupinside操作,而ScrollView中较小的按钮有自己的touchupinside选择器

  • 我的一些窗口工作得很好,如果我触摸屏幕上的任何地方,就会调用较大的按钮操作,如果我触摸并拖动,滚动就会工作并导航到下一个/上一个窗口,如果我触摸滚动视图中的较小按钮,它们的操作就会启动,最后我可以在这些按钮内完美滚动
  • 在我的一些窗口中,当我尝试滚动滚动视图时,较大的windows PangestureRecognitor会捕获此事件而不是较小的滚动视图,如果我在滚动视图中触摸小按钮,则会触发较大的按钮事件(它通过uibutton>uiscrollview>uiimageview>uiview传递到按钮处的uibutton,就像它们不存在一样)
  • 如果我将右容器视图替换为大uibutton上的某个其他位置,它会随机工作正常或不正常,有时其中一个ScrollView工作正常,而另一个则不正常
  • 它有一个一致的行为,如果在一个位置上,它起作用,它总是起作用,如果不起作用,它永远不会起作用
  • 同样,所有视图和子类都启用了userinteraction是的,相反的情况已经不可能了,因为行为只会根据容器视图在大uibutton上的位置而改变,也会根据大uibuttons背景图像而改变
  • 我放置了一个touchesbeent方法,仅用于测试目的,当触摸未按预期工作时,使用touch.view触发的事件是大按钮的容器,即使我触摸了ScrollView中的一个小按钮
我已经为此花了两天时间,但没有结果。什么会导致这种行为

编辑:在krumelur的评论之后,我将我的焦点从这些视图的配置改为容器视图的动画,我注意到,问题是关于动画,我添加了代码部分,该部分为所有十个窗口设置动画,行为类似于自定义滚动视图。所有窗口都有其自定义层类,当我捕获时pangesture识别器我用以下代码在屏幕上移动窗口。代码中的项目是一个数组,包含所有窗口的层。动画导致了这种奇怪的情况,但我还不知道

- (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];}

最后我发现,即使我使用
CATTransferorM3DMakeTransation
layer.zPosition
设置发回视图,触摸事件也会根据帧位置进入视图。当前甚至看不到的视图(被其他视图覆盖)仍会捕捉触摸。只编写一行代码(
[self.superview为当前屏幕上的视图带来subview-tofront:self]
)解决了问题

为了测试它并理解我所说的内容,我制作了一个简单的测试应用程序,它只有两个按钮。
蓝色和黄色按钮。蓝色按钮覆盖黄色按钮,因此您只能在开头看到蓝色按钮。
在蓝色按钮的内部代码润色上,我只是用
buttons.layer.zPosition=-1
将其发回。之后,屏幕上没有蓝色按钮的可见部分,我现在只看到黄色按钮,但当我触摸黄色按钮(或我认为我正在触摸它)时,仍然会运行蓝色按钮的内部代码润色

我不确定这是否是理想的逻辑,但对我来说似乎不合理


如上所述,编写
[blueButton.superview sendSubviewToBack:blueButton]
在将其图层设置为-1时,正如预期的那样工作。

最后我发现,即使我使用
CATTransferorM3DMakeTransation
layer.zPosition
设置发回视图,触摸事件也会根据其帧位置转到视图。当前甚至看不到的视图(被其他人覆盖)仍能捕捉到触感。只需为当前屏幕上的视图编写一行代码(
[self.superview bringsubview tofront:self]
)即可解决问题

为了测试它并理解我所说的内容,我制作了一个简单的测试应用程序,它只有两个按钮。
蓝色和黄色按钮。蓝色按钮覆盖黄色按钮,因此您只能在开头看到蓝色按钮。
在蓝色按钮的内部代码润色上,我只是用
buttons.layer.zPosition=-1
将其发回。之后,屏幕上没有蓝色按钮的可见部分,我现在只看到黄色按钮,但当我触摸黄色按钮(或我认为我正在触摸它)时,仍然会运行蓝色按钮的内部代码润色

我不确定这是否是理想的逻辑,但对我来说似乎不合理

如上所述,在将层设置为-1时编写
[blueButton.superview sendSubviewToBack:blueButton]

会带来subvi