5

バッキング レイヤーに CAKeyframeAnimation があり、その「パス」として単純な直線パスが設定されている UIView があります。
いわばアニメーションを「フリーズ」させて、進行状況を手動で変更することはできますか?
例: パスの長さが 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、を手動で設定layerしたりできます。簡単な一時停止/再開方法の例:0timeOffset

- (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 に答える