myIntというNSIntegerプロパティを持つCALayerサブクラスMyLayerがあります。このプロパティをCABasicAnimationでアニメートしたいのですが、CABasicAnimationはいわゆる「アニメート可能な」プロパティ(境界、位置など)でのみ機能するようです。カスタムmyIntプロパティをアニメート可能にするためにオーバーライドできるものはありますか?
3 に答える
はい、可能です(ただし、最新のCore Animationリリース、つまりiPhone3.0以降とOSX 10.6以降でのみ可能です)。
CAがアクセサーを実装するように、プロパティを動的にします。
@dynamic myInt;
プロパティの変更には再描画が必要であることをレイヤーに通知します。
+ (BOOL)needsDisplayForKey:(NSString*)key { if ([key isEqualToString:@"myInt"]) { return YES; } else { return [super needsDisplayForKey:key]; } }
メソッドでの値を使用
myInt
しますdrawInContext:
。これで、アニメーション化myInt
すると、Core Animationはアニメーションの各ステップの値を補間し、レイヤーにそれ自体を描画するよう繰り返し要求します。このプロパティの暗黙的なアニメーションも有効にする場合は、もオーバーライドします
actionForKey:
。
カスタム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:メソッドもオーバーライドする必要があります。
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)
}