CAKeyframeAnimation Manual Progress

I have a UIView whose backing layer has a CAKeyframeAnimation with a simple straight line set to "path".
Can I make the animation freeze, so to speak, and manually change its progress?
For example: If the path has a length of 100 points, then to set the progress (offset?) To 0.45 it follows that the viewpoint moves 45 points down the path.

I remember seeing an article that did something similar (moving the view along a path based on the value from the slider) through the CAMediaTiming interfaces, but I could not find it even after several hours of searching. If I approach this completely wrong, please let me know. Thank you

Here is an example code if the above is not clear enough.

- (void)setupAnimation { CAKeyFrameAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:_label.layer.position]; [path addLineToPoint:(CGPoint){200, 200}]; animation.path = path.CGPath; animation.duration = 1; animation.autoreverses = NO; animation.removedOnCompletion = NO; animation.speed = 0; // _label is just a UILabel in a storyboard [_label.layer addAnimation:animation forKey:@"LabelPathAnimation"]; } - (void)sliderDidSlide:(UISlider *)slider { // move _label along _animation.path for a distance that corresponds to slider.value } 
+4
source share
2 answers

This is based on what Jonathan said, only a little more. The animation is set up correctly, but the slider action method should be as follows:

 - (void)sliderDidSlide:(UISlider *)slider { // Create and configure a new CAKeyframeAnimation instance CAKeyframeAnimation *animation = ...; animation.duration = 1.0; animation.speed = 0; animation.removedOnCompletion = NO; animation.timeOffset = slider.value; // Replace the current animation with a new one having the desired timeOffset [_label.layer addAnimation:animation forKey:@"LabelPathAnimation"]; } 

This will move the label along the path animation based on timeOffset .

+1
source

Yes, you can do this using the CAMediaTiming interface. You can set speed from layer to 0 and manually set timeOffset . An example of a simple pause / resume method:

 - (void)pauseAnimation { CFTimeInterval pausedTime = [yourLayer convertTime:CACurrentMediaTime() fromLayer:nil]; yourLayer.speed = 0.0; yourLayer.timeOffset = pausedTime; } - (void)resumeAnimation { CFTimeInterval pausedTime = [yourLaye timeOffset]; if (pausedTime != 0) { yourLayer.speed = 1.0; yourLayer.timeOffset = 0.0; yourLayer.beginTime = 0.0; CFTimeInterval timeSincePause = [yourLayer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime; yourLayer.beginTime = timeSincePause; } } 
+1
source

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


All Articles