トップ «前の日記(2012-12-15) 最新 次の日記(2012-12-20)» 編集

Cocoa練習帳

iOS/iPhone/iPad/watchOS/tvOS/MacOSX/Android プログラミング, Objective-C, Cocoa, Swiftなど

2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|10|11|12|
2022|01|02|03|04|05|06|07|08|09|10|11|12|
2023|01|02|03|04|05|06|07|08|09|10|11|12|
2024|01|02|03|

2012-12-19 [OSX][iOS]Cocoa Animation

自分自身への冬休みの宿題として、Core Animationを課題としてあげる事にした。

教科書は、『Core Animation for Max OS X and the iPhone』だ。

宿題に取り組む前は、上記教科書の章立てについて疑問があったが、よくよく、読んでみると、関係性に気がついたので、それを説明してみることにした。

OS X限定となってしまうが、AppKitには、NSAnimatablePropertyContainerプトロコルを利用した、UIのアニメーション機能がある。このプロトコルの定義は以下のとおり。

  • Getting the Animator Proxy
    • - (id)animator
  • Managing Animations for Properties
    • - (NSDictionary *)animations
    • - (void)setAnimations:(NSDictionary *)dict
    • - (id)animationForKey:(NSString *)key
    • + (id)defaultAnimationForKey:(NSString *)key

使用方法は、以下のとおり。

マウス・クリックされると画像の位置が変化するプログラムの例だ。

@interface BaseView ()
@property (strong, nonatomic) NSImageView   *mover;
@property (assign, nonatomic) NSRect        leftFramePosiotion;
@property (assign, nonatomic) NSRect        rightFramePosiotion;
@property (assign, nonatomic) BOOL          isRight;
- (void)initializeFramePositions;
- (void)addImageToSubview;
- (void)move;
@end
 
@implementation BaseView
 
@synthesize mover = _mover;
@synthesize leftFramePosiotion = _leftFramePosiotion;
@synthesize rightFramePosiotion = _rightFramePosiotion;
@synthesize isRight = _isRight;
 
- (id)initWithFrame:(NSRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self initializeFramePositions];
        [self addImageToSubview];
        [self addSubview:self.mover];
    }
    
    return self;
}
 
- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self initializeFramePositions];
        [self addImageToSubview];
        [self addSubview:self.mover];
    }
    
    return self;
}
 
- (void)drawRect:(NSRect)dirtyRect
{
}
 
- (BOOL)acceptsFirstResponder
{
    return YES;
}
 
- (void)mouseDown:(NSEvent*)theEvent
{
    [self move];
}
 
- (void)initializeFramePositions
{
    CGFloat frameX = NSWidth(self.frame);
    CGFloat frameY = NSHeight(self.frame);
    self.leftFramePosiotion = NSMakeRect(0.0, 0.0, frameX / 4.0, frameY / 4.0);
    self.rightFramePosiotion = NSMakeRect(7.0 * frameX / 8.0, 7.0 * frameY / 16.0, frameX / 8.0, frameY / 8.0);
    self.mover = [[NSImageView alloc] initWithFrame:self.leftFramePosiotion];
    self.isRight = NO;
}
 
- (void)addImageToSubview
{
    [self.mover setImageScaling:NSScaleToFit];
    [self.mover setImage:[NSImage imageNamed:@"snapshot.jpg"]];
}
 
- (void)move
{
    if (self.isRight) {
        [self.mover setFrame:self.leftFramePosiotion];
    }
    else {
        [self.mover setFrame:self.rightFramePosiotion];
    }
    self.isRight = !self.isRight;
}
 
@end

setFrame:メソッドで画像の位置が変わるのだが、これにAnimatorプロキシを加えると、アニメーションするようになる。変更するのは、moveメソッドだ。

- (void)move
{
    if (self.isRight) {
        [[self.mover animator] setFrame:self.leftFramePosiotion];
    }
    else {
        [[self.mover animator] setFrame:self.rightFramePosiotion];
    }
    self.isRight = !self.isRight;
}

何が発生したのか説明すると、setFrame:でプロパティに対して変更が発生すると、それを契機にアニメーションしだす。プロパティ名をキーにしてanimationForKey:で利用するアニメーションを取得する。キーに対応した値は、valueForKey:で取得する。キーに対応するアニメーションが見つからない場合で、defaultAnimationForKey:でデフォルトのアニメーションを取得する。それでも見つからない場合はアニメーションしない。

次回からは、このとおりに動作していることを、要素毎に試行錯誤して確認してみようと思っている。

_ 【Cocoa練習帳】

http://www.bitz.co.jp/weblog/
http://ameblo.jp/bitz/(ミラー・サイト)

トップ «前の日記(2012-12-15) 最新 次の日記(2012-12-20)» 編集