30

myIntというNSIntegerプロパティを持つCALayerサブクラスMyLayerがあります。このプロパティをCABasicAnimationでアニメートしたいのですが、CABasicAnimationはいわゆる「アニメート可能な」プロパティ(境界、位置など)でのみ機能するようです。カスタムmyIntプロパティをアニメート可能にするためにオーバーライドできるものはありますか?

4

3 に答える 3

69

はい、可能です(ただし、最新のCore Animationリリース、つまりiPhone3.0以降とOSX 10.6以降でのみ可能です)。

  1. CAがアクセサーを実装するように、プロパティを動的にします。

    @dynamic myInt;
    
  2. プロパティの変更には再描画が必要であることをレイヤーに通知します。

    + (BOOL)needsDisplayForKey:(NSString*)key {
        if ([key isEqualToString:@"myInt"]) {
            return YES;
        } else {
            return [super needsDisplayForKey:key];
        }
    }
    
  3. メソッドでの値を使用myIntしますdrawInContext:。これで、アニメーション化myIntすると、Core Animationはアニメーションの各ステップの値を補間し、レイヤーにそれ自体を描画するよう繰り返し要求します。

  4. このプロパティの暗黙的なアニメーションも有効にする場合は、もオーバーライドしますactionForKey:

于 2010-03-07T13:53:08.753 に答える
6

カスタムCALayerサブクラスのiVarを保持する方法があります。カスタムレイヤーのコピーを作成するために呼び出されるメソッドであるinitWithLayer:をオーバーライドします。たとえば、「angle」というカスタムプロパティを作成するレイヤーがある場合は、次のコードを使用できます。

@implementation AngledLayer
@synthesize angle = _angle

// Tell Core Animation that this key should be animated
+ (BOOL) needsDisplayForKey:(NSString *)key
{
    if ([key isEqualToString:@"angle"]) return YES;
    return [super needsDisplayForKey:key];
}


// Make sure that, when the layer is copied, so is the custom ivar
- (id) initWithLayer:(id)layer
{
    self = [super initWithLayer:layer];
    if (self) {
        AngledLayer *angledVersion = (AngledLayer *)layer;
        self.angle = angledVersion.angle;
    }
    return self;
}

そして、ボブはあなたのおじです!このオブジェクトを暗黙のアニメーションで使用することはできないことに注意してください。このためには、actionForKey:メソッドもオーバーライドする必要があります。

于 2012-03-09T20:44:47.773 に答える
0

Swiftバージョン

// Custom property
@NSManaged public var progress: CGFloat
    
open override class func needsDisplay(forKey key: String) -> Bool {
    if key == "progress" {
        return true
    }
    return super.needsDisplay(forKey: key)
}
于 2021-05-30T21:38:31.237 に答える