「Xcodeでストーリーボードを編集するだけでアニメーションを可能にするライブラリCanvasを試す」で紹介したライブラリCanvasの仕組みがどうなっているのか気になったので調べてみました。
まずは、Custom Classに指定しているCSAnimationViewのヘッダファイルCSAnimationView.hを見てみます。
@interface CSAnimationView : UIView @property (nonatomic) NSTimeInterval delay; @property (nonatomic) NSTimeInterval duration; @property (nonatomic, copy) CSAnimationType type; @property (nonatomic) BOOL pauseAnimationOnAwake; // If set, animation wont starts on awakeFromNib @end
普通にプロパティを作っているだけでした。これだけで、User Defined Runtime Attributesで指定できるようになるんですね。
CSAnimationTypeもCAAnimation.hによると、文字列なので問題なし。
typedef NSString *CSAnimationType; static CSAnimationType CSAnimationTypeBounceLeft = @"bounceLeft";
続いて、実装を見ましょう (CSAnimationView.m)。
@implementation CSAnimationView
- (void)awakeFromNib {
if (self.type && self.duration && ! self.pauseAnimationOnAwake) {
[self startCanvasAnimation];
}
}
- (void)startCanvasAnimation {
Class <CSAnimation> class = [CSAnimation classForAnimationType:self.type];
[class performAnimationOnView:self duration:self.duration delay:self.delay];
[super startCanvasAnimation];
}
@end
@implementation UIView (CSAnimationView)
- (void)startCanvasAnimation {
[[self subviews] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[obj startCanvasAnimation];
}];
}
@end
CSAnimationのclassForAnimationType:で文字列からクラスに変換し、そのクラスがperformAnimationOnViewすることでアニメーションしています。
では、そのアニメーションサブクラスのひとつであるCSBounceLeftのインタフェースと実装を見てみましょう。
@interface CSBounceLeft : CSAnimation
@end
@implementation CSBounceLeft
+ (void)load {
[self registerClass:self forAnimationType:CSAnimationTypeBounceLeft];
}
+ (void)performAnimationOnView:(UIView *)view duration:(NSTimeInterval)duration delay:(NSTimeInterval)delay {
// Start
view.transform = CGAffineTransformMakeTranslation(300, 0);
[UIView animateKeyframesWithDuration:duration/4 delay:delay options:0 animations:^{
// End
view.transform = CGAffineTransformMakeTranslation(-10, 0);
} completion:^(BOOL finished) {
[UIView animateKeyframesWithDuration:duration/4 delay:0 options:0 animations:^{
// End
view.transform = CGAffineTransformMakeTranslation(5, 0);
} completion:^(BOOL finished) {
[UIView animateKeyframesWithDuration:duration/4 delay:0 options:0 animations:^{
// End
view.transform = CGAffineTransformMakeTranslation(-2, 0);
} completion:^(BOOL finished) {
[UIView animateKeyframesWithDuration:duration/4 delay:0 options:0 animations:^{
// End
view.transform = CGAffineTransformMakeTranslation(0, 0);
} completion:^(BOOL finished) {
}];
}];
}];
}];
}
@end
インタフェースは空で、実装はクラスメソッドが2つあるだけです。
+performAnimationOnView:duration:delay:はアニメーション実行コードです。
@implementation CSAnimation
static NSMutableDictionary *_animationClasses;
+ (void)load {
_animationClasses = [[NSMutableDictionary alloc] init];
}
+ (void)registerClass:(Class)class forAnimationType:(CSAnimationType)animationType {
[_animationClasses setObject:class forKey:animationType];
}
+ (Class)classForAnimationType:(CSAnimationType)animationType {
return [_animationClasses objectForKey:animationType];
}
@end
CSAnimationViewで使われていたclassForAnimationType:もありますね。
このクラスでは、文字列→クラスの解決と、そのための辞書への登録の口があるだけでした。
そして、この辞書への要素追加は、各アニメーションサブクラスの+loadで行うようになっていることがわかります。
おわりに
ライブラリCanvasの内部を紹介しました。
非常にシンプルなので拡張も非常にしやすそうですね。

0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。