确定触摸了哪个子视图

时间:2012-02-19 22:51:52

标签: iphone animation

我正在试用iPhone的动画内容,我有一个小应用程序,其中有圆圈从屏幕顶部落到底部。我在动画中添加了UIViewAnimationOptionAllowUserInteraction选项,并在子视图和主视图上设置了userInteractionEnabled = YES。每次我的NSTimer触发时,我都会以编程方式生成子视图,这会产生圆圈。

我遇到的问题是,即使我在我的主视图和子视图上实现- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event,事件也只会在主视图上触发,无论我有多么困难或多少次粉碎掉落的圆圈。

如何在我的圈子中触发该事件?为什么触摸不会触发顶部的视图?

1 个答案:

答案 0 :(得分:2)

问题在于,当您使用Core Animation执行“补间”动画时(使用UIView动画方法时隐式发生),新值会立即应用于所谓的{{3} }。

动画将提交给Core Animation,下次主运行循环发生时,Core Animation会进行必要的渲染,使其看起来好像正在发生动画。但实际上,您的视图的模型值(例如,其frametransform属性)会立即更改。

尝试点按屏幕底部按钮所在的位置(假设它们在屏幕上完成)。如果您这样做,它应该按照您的预期响应互动事件。

您可以通过不断触发计时器并在每一步应用较小的更改来手动更改圆圈的框架。然而,这可能并不理想。

另一个选择是使用视图的图层presentationLayer方法。该层表示任何时间点的图层状态,正如我们在屏幕上看到的那样。在我的脑海中,我想你的主视图的触摸处理方法可以迭代每个子视图并检查触摸点是否与子视图的图层的表示层的帧相交。如果确实如此,则表示有人“触动”了您的子视图。

for (UIView *subview in self.subviews)
{
    CALayer *presentationLayer = (CALayer *)[subview.layer presentationLayer];

    if (CGRectContainsPoint(presentationLayer.frame, touchPoint)
    {
        // Found the subview the user touched
    }
}

我应该注意presentationLayer返回id,因为表示层可能是CALayer或其任何子类。因此,例如,如果您使用CAShapeLayer,那么-presentationLayer将返回CAShapeLayer。尽管如此,将其强制转换为CALayer也没关系,因为您为此任务的目的所关心的只是检查其frame属性。