5

我有一个 UIView,其支持层有一个 CAKeyframeAnimation,它的“路径”设置为简单的直线路径。
我可以让动画“冻结”,可以这么说,并手动更改其进度吗?
例如:如果路径的长度为 100 点,则将进度(偏移量?)设置为 0.45 会使视图沿路径向下移动 45 点。

我记得看到一篇文章通过 CAMediaTiming 接口做了类似的事情(根据滑块的值沿路径移动视图),但即使经过几个小时的搜索,我也无法找到它。如果我以完全错误的方式处理这个问题,请告诉我。谢谢。

如果以上内容不够清楚,这里有一些示例代码。

- (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

2 回答 2

3

这是基于乔纳森所说的,只是更重要一点。动画设置正确,但滑块动作方法应该如下:

- (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"];
}

这将使标签沿着动画的path基础移动timeOffset

于 2013-07-04T18:16:35.783 回答
1

是的,您可以使用 CAMediaTiming 界面执行此操作。您可以将 设置为speed并手动设置。一个简单的暂停/恢复方法示例:layer0timeOffset

- (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;
    }
}
于 2013-07-04T08:38:25.330 回答