Limit effect of UIPercentDrivenInteractiveTransiti

2019-06-07 22:52发布

问题:

Is there a way to limit the effect of UIPercentDrivenInteractiveTransition to only the topmost view in a view hierarchy?

Specifically: as explained here and here the interactive transition sets the container view layer's speed to 0 and then manipulates the timeOffset to scrub through the transition.

If for example I have an activity indicator in that containing view, the interactive transition also scrubs through the activity indicator's spin animation. It stops spinning and appears to "roll" forward and back with the interactive transition.

Is there a way to localize the effect of setting speed and timeOffset and prevent them from propagating through to any or all subviews?

So far, I can think of two possible approaches:

  1. Create a "barrier" layer: subclass CALayer and override setTimeOffset: to prevent or selectively prevent changes

  2. Subclass or replace UIPercentDrivenInteractiveTransition with something that traverses the subview hierarchy and selectively hits only certain views

Any other ideas would be welcome.

回答1:

You should tell the activity animator to stop animating, but keep it visible, during the transition. This is consistent with how Apple handles this in its apps. For example, in the Mail app, do pull-to-refresh to get new messages. While the indicator is spinning, use the interactive pop gesture recognizer to about halfway. Notice that the activity indicator stops during the interactive transition.



回答2:

Why don't you just hide the activity indicator for the duration of the animation? Surely it has no purpose being there, has it? After all, it cannot mean "animation is in progress" - the user does not sense this as an animation, or even as a time-consuming transition, but as a gesture being driven by a finger. You can easily show it again when the animation is over, by using the animation's completion handler.



回答3:

The answer to this question is no. According to Apple, the CALayer class adopts CAMediaTiming "allowing a layer to define a timespace relative to its superlayer". In other words, whatever values of timeOffset or beginTime are specified in a child layer are summed with the layers above. As the docs state, "This concept of a layer-tree timespace provides a scalable timeline that starts at the root layer, through its descendants."

The UIPercentDrivenInteractiveTransition acts by scrubbing through the timeOffset of [transitionContext containerView].layer. (transitionContext is an id<UIViewControllerContextTransitioning>).

Therefore it is applying a time offset that is then automatically adopted by all child layers down the sublayer chain.

There is no such thing as a "barrier" or "selectively hitting only certain layers" because this time propagation is handled by Core Animation internally.