Domanda

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?

È stato utile?

Soluzione

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.

Altri suggerimenti

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top