Strange behavior, animating a UIView using [UIView animateKeyframesWithDuration]

I am trying to create an effect when three arrows go from visible to invisible as an alternative.

I made a simple algorithm in which each arrow began with a different alpha value (if there are 3 arrows, the first starts with alpha = 1, the second with alpha = 0.6667, the third with alpha = 0.3337). Then I run the keyframe animation, which:

  • Change the opacity of the arrow from the current alpha to 0 (duration calculated)
  • Set the opacity of the arrow to 1
  • Change the opacity of the arrow from 1 to the first value

However, it seems that some step is being skipped for some reason.

A simple example:

[UIView animateKeyframesWithDuration:2 delay:0 options:UIViewKeyframeAnimationOptionCalculationModeLinear | UIViewKeyframeAnimationOptionRepeat animations:^{ [UIView addKeyframeWithRelativeStartTime:0 relativeDuration:0 animations:^{ _animatedView.alpha = 0.5; }]; [UIView addKeyframeWithRelativeStartTime:0 relativeDuration:0.5 animations:^{ _animatedView.alpha = 0; }]; [UIView addKeyframeWithRelativeStartTime:0.5 relativeDuration:0 animations:^{ _animatedView.alpha = 1; }]; [UIView addKeyframeWithRelativeStartTime:0.5 relativeDuration:0.5 animations:^{ _animatedView.alpha = 0.5; }]; } completion:nil]; 

In this case, it should go to 0.5 instantly, from 0.5 to 0 in 1 second, go to 1 instantly, from 1 to 0.5 in 1 second. Therefore, he should make a smooth transition that looks like the view appears and disappears, but it looks like the animation is stuck at alpha = 0.5 for a few seconds.

Theoretically, the effect should be the same as when using this keyframe animation:
 [UIView animateKeyframesWithDuration:2 delay:0 options:UIViewKeyframeAnimationOptionCalculationModeLinear | UIViewKeyframeAnimationOptionRepeat animations:^{ [UIView addKeyframeWithRelativeStartTime:0 relativeDuration:0 animations:^{ _animatedView.alpha = 1; }]; [UIView addKeyframeWithRelativeStartTime:0 relativeDuration:1 animations:^{ _animatedView.alpha = 0; }]; } completion:nil]; 
+5
source share
1 answer

If you want to animate N views in the same way:

 CGFloat count = [self.animatedViews count]; CGFloat period = 1.0f / count; __weak NSArray *weakViews = self.animatedViews; [UIView animateKeyframesWithDuration:2.0f delay:0 options:UIViewKeyframeAnimationOptionCalculationModeLinear | UIViewKeyframeAnimationOptionRepeat animations:^{ for (NSUInteger index = 0; index < count; ++index) { UIView *animatedView = weakViews[index]; CGFloat startDelay = period * index; [UIView addKeyframeWithRelativeStartTime:0 relativeDuration:0 animations:^{ animatedView.alpha = startDelay; }]; [UIView addKeyframeWithRelativeStartTime:0.0f relativeDuration:startDelay animations:^{ animatedView.alpha = 0.0f; }]; [UIView addKeyframeWithRelativeStartTime:startDelay relativeDuration:0.0f animations:^{ animatedView.alpha = 1.0f; }]; [UIView addKeyframeWithRelativeStartTime:startDelay relativeDuration:(1.0f - startDelay) animations:^{ animatedView.alpha = startDelay; }]; } } completion:nil]; 
0
source

Source: https://habr.com/ru/post/1201343/


All Articles