トップ «前の日記(2013-01-03) 最新 次の日記(2013-01-05)» 編集

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|

2013-01-04 [OSX][iOS]アニメーションの種類(グループ)

複数のアニメーションをグループ化する事が出来る。

- (CAAnimationGroup *)groupAnimation
{
    CAAnimationGroup    *animation = [CAAnimationGroup animation];
    animation.animations = [NSArray arrayWithObjects:
                            [self opacityAnimation],
                            [self originAnimation], nil];
    animation.duration = 4.0;
    return animation;
}

この場合、アニメーションのキーは、実行する契機という意味になってしまう。

self.mover.animations = [NSDictionary dictionaryWithObjectsAndKeys:
                         [self groupAnimation], @"alphaValue", nil];

なので、個々のアニメーションは何のパスを変化させる物なのかの指定がインスタンスの生成時に必要になる。

CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"alphaValue"];
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"frameOrigin"];

以前、紹介したコードから色々変わっているので、全体のコードを掲載する。

#import <QuartzCore/QuartzCore.h>
#import "BaseView.h"
  
@interface BaseView ()
@property (strong, nonatomic) NSImageView   *mover;
@property (assign, nonatomic) NSRect        leftFramePosiotion;
@property (assign, nonatomic) NSRect        rightFramePosiotion;
@property (assign, nonatomic) BOOL          isRight;
@property (assign, nonatomic) CGMutablePathRef  heartPath;
- (void)initializeFramePositions;
- (void)addImageToSubview;
- (void)move;
- (CAKeyframeAnimation *)opacityAnimation;
@end
 
@implementation BaseView
 
@synthesize mover = _mover;
@synthesize leftFramePosiotion = _leftFramePosiotion;
@synthesize rightFramePosiotion = _rightFramePosiotion;
@synthesize isRight = _isRight;
@synthesize heartPath = _heartPath;
 
- (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];
    */
    CGFloat xInset = 3.0 * (NSWidth(self.frame) / 8.0);
    CGFloat yInset = 3.0 * (NSHeight(self.frame) / 8.0);
    NSRect  moverFrame = NSInsetRect(self.frame, xInset, yInset);
    self.mover = [[MyImageView alloc] initWithFrame:moverFrame];
    self.isRight = NO;
    self.heartPath = NULL;
    
    /*
    self.mover.animations = [NSDictionary dictionaryWithObjectsAndKeys:
                             [self opacityAnimation], @"alphaValue",
                             [self originAnimation], @"frameOrigin", nil];
    */
    self.mover.animations = [NSDictionary dictionaryWithObjectsAndKeys:
                             [self groupAnimation], @"alphaValue", nil];
}
 
- (void)addImageToSubview
{
    [self.mover setImageScaling:NSScaleToFit];
    [self.mover setImage:[NSImage imageNamed:@"snapshot.jpg"]];
}
 
- (void)move
{
    /*
    if (self.isRight) {
        [[self.mover animator] setFrame:self.leftFramePosiotion];
    }
    else {
        [[self.mover animator] setFrame:self.rightFramePosiotion];
    }
    self.isRight = !self.isRight;
    */
    [[self.mover animator] setAlphaValue:1.0];
    /*
    NSRect  rect = self.mover.frame;
    [[self.mover animator] setFrameOrigin:rect.origin];
    */
}
 
- (CAKeyframeAnimation *)opacityAnimation
{
    //CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"alphaValue"];
    animation.duration = 4.0;
    animation.values = [NSArray arrayWithObjects:
                        [NSNumber numberWithFloat:0.0],
                        [NSNumber numberWithFloat:0.75],
                        [NSNumber numberWithFloat:0.0], nil];
    animation.keyTimes = [NSArray arrayWithObjects:
                          [NSNumber numberWithFloat:0.25],
                          [NSNumber numberWithFloat:0.50],
                          [NSNumber numberWithFloat:0.75], nil];
    animation.timingFunctions = [NSArray arrayWithObjects:
                                 [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn],
                                 [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut], nil];
    return animation;
}
 
- (CABasicAnimation *)opacityAnimationBasic
{
    CABasicAnimation *animation = [CABasicAnimation animation];
    animation.duration = 4.0;
    //animation.repeatCount = 2;
    //animation.autoreverses = YES;
    animation.fromValue = [NSNumber numberWithFloat:1.0];
    animation.toValue = [NSNumber numberWithFloat:0.0];
    return animation;
}
 
- (CAKeyframeAnimation *)originAnimation
{
    //CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"frameOrigin"];
    animation.duration = 4.0;
    animation.path = self.heartPath;
    animation.calculationMode = kCAAnimationPaced;
    return animation;
}
 
- (CGMutablePathRef)heartPath
{
    if (! _heartPath) {
        NSRect  frame = self.mover.frame;
        _heartPath = CGPathCreateMutable();
        CGPathMoveToPoint(_heartPath, NULL, NSMinX(frame), NSMinY(frame));
        CGPathAddLineToPoint(_heartPath, NULL,
                             NSMinX(frame) - NSWidth(frame),
                             NSMinY(frame) + NSHeight(frame) * 0.85);
        CGPathAddLineToPoint(_heartPath, NULL,
                             NSMinX(frame),
                             NSMinY(frame) - NSHeight(frame) * 1.5);
        CGPathAddLineToPoint(_heartPath, NULL,
                             NSMinX(frame) + NSWidth(frame),
                             NSMinY(frame) + NSHeight(frame) * 0.85);
        CGPathAddLineToPoint(_heartPath, NULL,
                             NSMinX(frame),
                             NSMinY(frame));
        CGPathCloseSubpath(_heartPath);
    }
    return _heartPath;
}
 
- (CAAnimationGroup *)groupAnimation
{
    CAAnimationGroup    *animation = [CAAnimationGroup animation];
    animation.animations = [NSArray arrayWithObjects:
                            [self opacityAnimation],
                            [self originAnimation], nil];
    animation.duration = 4.0;
    return animation;
}
 
@end

_ 【Cocoa練習帳】

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

トップ «前の日記(2013-01-03) 最新 次の日記(2013-01-05)» 編集