在动画 UIView/CALayer 中处理触摸的最佳模式?

发布于 2025-01-05 16:49:16 字数 593 浏览 0 评论 0原文

我有一个使用 CAKeyframeAnimation 为其设置动画的 UIView 实例。这是一个循环动画,并且会不断运动。但是,我需要允许用户与该项目交互(确切地说,响应点击)。由于 CoreAnimation 仅移动表示层而不是模型,因此我无法使用 UIButton 实例来本质上获取 touchUpInside 事件。

考虑以下基本示例布局:

在此处输入图像描述

我通过覆盖 将蓝色框用于触摸事件UIView 子类上的touchesEnded:withEvent: 方法。然后,我通过 NSNotification(我真的不想引入大量耦合来处理此事件)将该事件冒泡到包含的视图控制器,然后视图控制器执行 hitTest:< /code> 正在动画的红色框上。

所有这一切对于仅仅能够触摸动画 UIView 来说似乎都相当老套。 处理动画 UIView/CALayer 实例的触摸的最佳模式是什么?

I have a UIView instance that I am animating using CAKeyframeAnimation. It is a looping animation and will be constantly in motion. However, I need to allow user interaction with the item (responding to taps, to be exact). Because CoreAnimation is only moving the presentation layer and not the model, I cannot use a UIButton instance, for example, to essentially get the touchUpInside events.

Consider the following basic example layout:

enter image description here

I am using the blue box for touch events by overriding the touchesEnded:withEvent: method on a UIView subclass. I am then bubbling that event through an NSNotification (I really don't want to introduce a lot of coupling to handle this event) to the containing view controller, which then does a hitTest: on the red box being animated.

All of this seems rather hacky to just be able to touch an animated UIView. What are some of the best patterns for handling touches for animated UIView/CALayer instances?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

短叹 2025-01-12 16:49:16

我相信在超级视图中跟踪触摸是正确的。但我会在超级视图中进行命中测试,而不是向视图控制器发布通知。像这样的事情:

创建一个 MYAnimationContainerView 类(蓝色框)。

为其提供所属视图控制器设置的委托或块回调。例如:

__weak id weakSelf = self;
MYAnimationContainerView *view = [[MYAnimationContainerView alloc] initWithTouchCallback:^(UIView *touchedView){
  [weakSelf handleTouchToView:touchedView];
}];

MYAnimationContainerView 中,覆盖 touchesBegan:withEvent:touchesEnded:withEvent:。在began中,对移动视图的表示层执行命中测试。跟踪哪一个(如果有)被触摸。在结束中,执行另一次命中测试。如果是相同的视图,则调用您的回调。

上述内容可以很容易地使用delegate协议而不是块来实现。我刚刚养成了更喜欢块而不是单一方法委托协议的习惯。

您也可以使用 target/selector 来实现它,但该模式已经成为 ARC 有点麻烦,我今天不鼓励使用它。

Tracking the touch in the superview is correct I believe. But I would do hit testing in the superview rather than posting a notification to the view controller. Something like this:

Create a MYAnimationContainerView class (the blue box).

Give it a delegate or block callback that the owning view controller sets. For example:

__weak id weakSelf = self;
MYAnimationContainerView *view = [[MYAnimationContainerView alloc] initWithTouchCallback:^(UIView *touchedView){
  [weakSelf handleTouchToView:touchedView];
}];

In MYAnimationContainerView, override both touchesBegan:withEvent: and touchesEnded:withEvent:. In began, perform a hit test on the presentation layer of the moving view(s). Keep track of which one (if any) was touched. In ended, perform another hit test. If it's the same view, then call your callback.

The above could just as easily be implemented with a delegate protocol rather than a block. I've just been getting in the habit of preferring blocks over one-method delegate protocols.

You could also implement it with target/selector, but that pattern has gotten to be a bit of a hassle with ARC, and I tend to discourage its use today.

︶ ̄淡然 2025-01-12 16:49:16

如果你想处理视图中特定对象的触摸,比如蓝色上的红色框,最好创建一个单独的类,比如 UIview 的子类,并在其中处理触摸事件。它干净而抽象。

对于许多此类对象,触摸事件由其自身处理。

我不确定这是否是您所期望的。

If you want to handle touch for particular object in a view, say the red box on the blue, It is better to create a separate class ,say subclass of UIview, and handle touch events in it. It is clean and abstract.

In case of many such objects, the touch events are handled by itself.

I am not sure this is what you expected.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文