「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 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。