21

で使用するためのかなり単純な CoreAnimation を作成しようとしていますAVComposition。私の目標はCALayer、さまざまなサブレイヤーを介して、タイトルをフェードインおよびフェードアウトし、次に画像をフェードインおよびフェードアウトする を作成することです。基本的にスライドショーです。これは、 を使用して .mov にエクスポートされていAVAssetWriterます。

WWDC 2011 AVEditDemo の助けを借りて、タイトルと画像を表示することができました。問題は、それらがすべて同時に画面に表示されることです。

各レイヤーを不透明度 0.0 で作成しました。CABasicAnimation次に、次のコードを使用して、それらを 0.0 から 1.0 にフェードする を追加しました。

CABasicAnimation *fadeInAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
fadeInAnimation.fromValue = [NSNumber numberWithFloat:0.0];
fadeInAnimation.toValue = [NSNumber numberWithFloat:1.0];
fadeInAnimation.additive = NO;
fadeInAnimation.removedOnCompletion = YES;
fadeInAnimation.beginTime = 1.0;
fadeInAnimation.duration = 1.0;
fadeInAnimation.fillMode = kCAFillModeForwards;
[titleLayer addAnimation:fadeInAnimation forKey:nil];

問題は「beginTime」プロパティにあるようです。「1.0」は遅延を意味するため、アニメーションの開始から 1 秒後に開始されます。ただし、すぐに画面に表示されます。フェードアウトのアニメーション

このコードの逆のフェード アウトでは、単純に fromValue を 1.0 に、toValue を 0.0 に変更します。開始時間が 4.0 で、完全に機能します。

を作成するために以下を使用していますanimatedTitleLayer

CATextLayer *titleLayer = [CATextLayer layer];
titleLayer.string =self.album.title;
titleLayer.font = @"Helvetica";
titleLayer.fontSize = videoSize.height / 6;
titleLayer.alignmentMode = kCAAlignmentCenter;
titleLayer.bounds = CGRectMake(0, 0, videoSize.width, videoSize.height / 6);
titleLayer.foregroundColor = [[UIColor redColor]CGColor];
titleLayer.opacity = 0.0;

イメージ フェードイン アニメーションの beginTime は 5 秒間隔です。タイトルのように、フェード アウト アニメーションは正常に機能します。

どんな助けでも大歓迎です!

乾杯!

編集

回答はすべて役に立ちましたが、最終的に、CALayer. フェードアウト アニメーションは、最後に追加されたものであったため、機能していました。

次に、CAAnimationGroup を試しましたが、同じキー値パスを変更していたため、これは機能しませんでした。

CAKeyframeAnimationだから、これにはaが最適だと気づきました。私だけがそれにも苦労しています!コードは正常にフェードインしていますが、フェードアウトしていません。さまざまなfillModeを試したり、期間を変更したりしましたが、うまくいきません!!

これが私のコードです:

    CAKeyframeAnimation *fadeInAndOut = [CAKeyframeAnimation animationWithKeyPath:@"opacity"];
    fadeInAndOut.duration = 5.0;
    fadeInAndOut.autoreverses = NO;
    fadeInAndOut.keyTimes = [NSArray arrayWithObjects:  [NSNumber numberWithFloat:0.0],
                                                            [NSNumber numberWithFloat:1.0],
                                                    [NSNumber numberWithFloat:4.0], 
                                                    [NSNumber numberWithFloat:5.0], nil];

    fadeInAndOut.values = [NSArray arrayWithObjects:    [NSNumber numberWithFloat:0.0],
                                                    [NSNumber numberWithFloat:1.0],
                                                    [NSNumber numberWithFloat:1.0], 
                                                    [NSNumber numberWithFloat:0.0], nil];
    fadeInAndOut.beginTime = 1.0;
    fadeInAndOut.removedOnCompletion = NO;
    fadeInAndOut.fillMode = kCAFillModeBoth;
    [titleLayer addAnimation:fadeInAndOut forKey:nil]; 
4

10 に答える 10

29

同じ問題に直面していますが、問題は、1つのレイヤーにフェードインとフェードアウトを含めることができないことです。だから、私がしたように、他のアニメーションを親レイヤーに追加することができます

CALayer *parentLayer = [CALayer layer];
CALayer *animtingLayer = [CALayer layer];

//FADE IN
        CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
        animation.beginTime = CMTimeGetSeconds(img.startTime);
        animation.duration = CMTimeGetSeconds(_timeline.transitionDuration);
        animation.fromValue = [NSNumber numberWithFloat:0.0f];
        animation.toValue = [NSNumber numberWithFloat:1.0f];
        animation.removedOnCompletion = NO;
        animation.fillMode = kCAFillModeBoth;
        animation.additive = NO;
        [parentLayer addAnimation:animation forKey:@"opacityIN"];

//FADE OUT
        CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
        animation.beginTime = CMTimeGetSeconds(CMTimeAdd(img.passTimeRange.start, img.passTimeRange.duration));
        animation.duration = CMTimeGetSeconds(_timeline.transitionDuration);
        animation.fromValue = [NSNumber numberWithFloat:1.0f];
        animation.toValue = [NSNumber numberWithFloat:0.0f];
        animation.removedOnCompletion = NO;
        animation.fillMode = kCAFillModeBoth;
        animation.additive = NO;
        [animtingLayer addAnimation:animation forKey:@"opacityOUT"];

    [parentLayer addSublayer:animtingLayer];
于 2012-07-04T10:26:17.043 に答える
26

男、非常に多くの複雑な答え。最も簡単な方法は、オートリバースを追加することです。出来上がり。

CABasicAnimation *fadeInAndOut = [CABasicAnimation animationWithKeyPath:@"opacity"];
fadeInAndOut.duration = 5.0;
fadeInAndOut.autoreverses = YES;
fadeInAndOut.fromValue = [NSNumber numberWithFloat:0.0];
fadeInAndOut.toValue = [NSNumber numberWithFloat:1.0];
fadeInAndOut.repeatCount = HUGE_VALF;
fadeInAndOut.fillMode = kCAFillModeBoth;
[titleLayer addAnimation:fadeInAndOut forKey:@"myanimation"];
于 2014-04-17T02:03:00.607 に答える
5

これは私のために働く:

 let fadeAnimation = CAKeyframeAnimation(keyPath:"opacity")
 fadeAnimation.beginTime = AVCoreAnimationBeginTimeAtZero + start
 fadeAnimation.duration = duration
 fadeAnimation.keyTimes = [0, 1/8.0, 5/8.0, 1]
 fadeAnimation.values = [0.0, 1.0, 1.0, 0.0]
 fadeAnimation.removedOnCompletion = false
 fadeAnimation.fillMode = kCAFillModeForwards
 layer.addAnimation(fadeAnimation, forKey:"animateOpacity")
 layer.opacity = 0.0
于 2015-08-07T20:18:32.170 に答える
1

試す:

fadeInAnimation.beginTime = CACurrentMediaTime()+1.0;
于 2012-01-03T02:12:20.340 に答える
1

LenKの答えは私にとって完璧に機能しました。興味のある方は、Obj-C 用に書き直しました (フェードインのキー フレームも少し変更したことに注意してください)。

CAKeyframeAnimation *fadeInAndOutAnimation = [CAKeyframeAnimation animationWithKeyPath:@"opacity"];
fadeInAndOutAnimation.beginTime = CACurrentMediaTime() + beginTime;
fadeInAndOutAnimation.duration = duration;
fadeInAndOutAnimation.keyTimes = @[@0.0, @( 2.0 / 8.0 ), @( 5.0 / 8.0 ), @1.0];
fadeInAndOutAnimation.values = @[@0.0, @1.0, @1.0, @0.0];
fadeInAndOutAnimation.removedOnCompletion = false;
fadeInAndOutAnimation.fillMode = kCAFillModeForwards;
于 2016-01-23T17:49:54.013 に答える
1

もう 1 つの方法は、CAAnimationGroup を使用することです。CAKeyframeAnimation も UI に対して適切に機能します。このコードは、ショー アニメーション リアルタイムの UI で正常に動作します。しかし、まったく機能しませんAVVideoCompositionCoreAnimationTool必要な場合は下にスクロールしてください。コピー&ペーストできるコードではありませんが、アイデアは得られます。また、グループに追加のアニメーションを追加することもできます:

for (HKAnimatedLayer *animLayer in layersList) {

    overlayLayer = [CALayer layer];
    [overlayLayer setContents:(id)[animLayer.image CGImage]];
    overlayLayer.frame = CGRectMake(0, 0, size.width, size.height);
    [overlayLayer setMasksToBounds:YES];

    NSMutableArray *animations = [NSMutableArray array];
    // Step 1
    {
        CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
        animation.toValue = @(0);
        animation.duration = kLayerFadeDuration;
        animation.beginTime = kMovieDuration/5;
        animation.fillMode = kCAFillModeForwards;
        [animations addObject:animation];
    }
    {
        CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
        animation.toValue = @(1.0);
        animation.duration = kLayerFadeDuration;
        animation.beginTime = kMovieDuration*2/3;
        animation.fillMode = kCAFillModeForwards;
        [animations addObject:animation];
    }

    CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
    animationGroup.animations = animations;
    animationGroup.duration = kMovieDuration;
    animationGroup.fillMode = kCAFillModeForwards;
    animationGroup.removedOnCompletion = YES;

    [overlayLayer addAnimation:animationGroup forKey:nil];

    [parentLayer addSublayer:overlayLayer];
}

ここでは、 のレイヤのアニメーションに関する小さな注意事項を示しAVVideoCompositionCoreAnimationToolます。関連する gif 画像が表示されます (タイトルは 1 つずつ表示され、消えます)。この問題を解決するために、2 つの別々CALayerの を使用します。これは、何らかの理由で 1 つのレイヤーopaqueで複数のレイヤーの 2 アニメーションが誤作動するためです。

AVVideoCompositionCoreAnimationTool

// set up the parent layer
CALayer *parentLayer = [CALayer layer];
parentLayer.frame = CGRectMake(0, 0, size.width, size.height);

// one layer for one animation
CALayer *overlayLayer, *barrierLayer;
CABasicAnimation *animation;

for (HKAnimatedLayer *animLayer in layersList) {
    overlayLayer = [CALayer layer];
    overlayLayer.contents = (id)[animLayer.image CGImage];
    overlayLayer.frame = CGRectMake(0, 0, size.width, size.height);
    overlayLayer.masksToBounds = YES;

    // layer with appear animation
    if (animLayer.fromTime != 0 && (animLayer.fromTime - kLayerFadeDuration)>0) {
        overlayLayer.opacity = 0.0;

        animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
        animation.fromValue = @(0);
        animation.toValue = @(1);
        animation.additive = NO;
        animation.removedOnCompletion = NO;
        animation.beginTime = animLayer.fromTime - kLayerFadeDuration;
        animation.duration = kLayerFadeDuration;
        animation.fillMode = kCAFillModeForwards;

        [overlayLayer addAnimation:animation forKey:@"fadeIn"];
    }

    if (animLayer.toTime == kMovieDuration) {
        [parentLayer addSublayer:overlayLayer];
    } else { // layer with dissappear animation
        barrierLayer = [CALayer layer];
        barrierLayer.frame = CGRectMake(0, 0, size.width, size.height);
        barrierLayer.masksToBounds = YES;
        [barrierLayer addSublayer:overlayLayer];

        animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
        animation.fromValue = @(1);
        animation.toValue = @(0);
        animation.additive = NO;
        animation.removedOnCompletion = NO;
        animation.beginTime = animLayer.toTime;
        animation.duration = kLayerFadeDuration;
        animation.fillMode = kCAFillModeForwards;

        [overlayLayer addAnimation:animation forKey:@"fadeOut"];
        [parentLayer addSublayer:barrierLayer];
    }
}

そして最後に、適切なアニメーションシーケンスを得ることができます右のアニメーション

于 2017-06-30T22:41:44.487 に答える
1

問題の核心は、CAKeyframeAnimation の keyTimes プロパティを理解していないことでした。この質問はそれをすべて明確にし、私を正しい道に導きました:

CAKeyFrameAnimation の keyTime はどのような値ですか?

于 2012-01-14T08:37:54.843 に答える