3

UIViewサブクラスには、次のメソッドがあります。

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch * aTouch = [touches anyObject];
    CGPoint loc = [aTouch locationInView:self];

    CALayer * layer = [CALayer layer];
    [layer setBackgroundColor: [[UIColor colorWithHue:(float)rand()/RAND_MAX saturation:1 brightness:1 alpha:1] CGColor]];
    [layer setFrame:CGRectMake(0, 0, 64, 64)];
    [layer setCornerRadius:7];
    [layer setPosition:loc];

    [layer setOpacity:0];

    [self.layer addSublayer:layer];


    CABasicAnimation * opacityAnim = [CABasicAnimation animationWithKeyPath:@"opacity"];
    opacityAnim.duration=2.42;
    opacityAnim.fromValue=[NSNumber numberWithFloat:0];
    opacityAnim.toValue=  [NSNumber numberWithFloat:1];
    opacityAnim.fillMode = kCAFillModeForwards;
    opacityAnim.timingFunction= [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
    opacityAnim.removedOnCompletion=NO;
    opacityAnim.delegate=self;

//  explicit animation is working as expected
//  [layer addAnimation:opacityAnim forKey:@"opacityAnimation"];

//     Why isn't the implicit animation working ?
[layer setOpacity:1];
}

私は何が欠けていますか?CALayerlayerの不透明度は、このメソッドの最後の行で暗黙的にアニメーション化されることを期待しています。

私の解決策

ダンカンの答えのおかげで、これが私が問題を解決した方法です。

-(CALayer *) layerFactory:(CGPoint) loc {
    CALayer * layer = [CALayer layer];
    [layer setBackgroundColor: [[UIColor colorWithHue:(float)rand()/RAND_MAX saturation:1 brightness:1 alpha:1] CGColor]];
    [layer setFrame:CGRectMake(0, 0, 64, 64)];
    [layer setCornerRadius:7];
    [layer setPosition:loc];
    [layer setOpacity:0];
    return layer;
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    UITouch * aTouch = [touches anyObject];
    CGPoint loc = [aTouch locationInView:self];


    [CATransaction begin];
    CALayer * layer = [self layerFactory:loc];
    [self.layer addSublayer:layer];
    [CATransaction commit];


    [CATransaction begin];
    [CATransaction setAnimationDuration:0.45];
    [layer setOpacity:1];
    [CATransaction commit];

}

レイヤーの作成と不透明度の変更を2つの異なるCATransactionブロックに配置するだけで済みます。ただし、レイヤーの作成(追加ではなく)をlayerFactoryメソッドに移動しても、状況は変わりません。

それが最善の解決策かどうかはわかりませんが、機能しています。

4

1 に答える 1

4

レイヤーを作成して不透明度を設定してから、同じメソッドで不透明度を新しい値に設定して、暗黙のアニメーションを取得することはできません。レイヤーコードの作成/構成をCATransactionの開始/終了ブロック内に配置してから、不透明度を1に設定するコードを別のトランザクションの開始/終了ブロック内に配置してみてください。

それはうまくいくと思いますが、確実に試してみる必要があります。

それが機能しない場合は、performSelector:withObject:afterDelayと遅延値0を使用して不透明度を1に設定するコードを呼び出します。これにより、システムは不透明度0のレイヤーを追加し、不透明度の変更を次のように処理します。個別のトランザクションとして1。

于 2013-03-20T13:40:36.320 に答える