ios动画学习(三)

使用Core Animation声明动画

CoreAnimation框架最基本的抽象类是CAAnimation类,这个类按照CAMediaTiming协议,提供了动画执行时间、速度,及重复次数这些基本设定,同时,它也遵循了CAAction协议,可提供该动画被图层驱动时的响应。
CAAnimation类之下定义了一系列的类,用来定义更具体的渐变动画类。层级如下:



下面是CABasicAnimation类使用:
- (IBAction)down:(id)sender {
    //使用CABasicAnimation建立动画,fromValue、toValue、byValue数值以oc对象形式存在
    CABasicAnimation * moveDown = [CABasicAnimation animationWithKeyPath:@"position.y"];
    //是视图在动画执行完成后,停留在最后位置
    //moveDown.removedOnCompletion = NO;
    //moveDown.fillMode = kCAFillModeForwards;
    
    //动画执行完成后,自动以动画形式原路返回
    //moveDown.autoreverses = YES;
    
    //动画重复执行的次数
    //moveDown.repeatCount = 2;
    moveDown.duration = 2.0;
    moveDown.toValue = [NSNumber numberWithInt:layer.position.y+100];
    //把动画应用到图层上,并且给动画加一个标识符moveDown
    [layer addAnimation:moveDown forKey:@"moveDown"];
}

- (IBAction)up:(id)sender {
    //使用CABasicAnimation建立动画
    //这种声明动画的方式改变的只有界面本身,而非对象属性。这和设定对象属性制作成的动画有非常大的区别。
    CABasicAnimation * moveUp = [CABasicAnimation animationWithKeyPath:@"position.y"];
    moveUp.duration = 5.0;
    //把正数封装成对象类型
    moveUp.toValue = [NSNumber numberWithInt:layer.position.y-100];
    //把动画应用到图层上,并且给动画加一个标识符moveUp
    [layer addAnimation:moveUp forKey:@"moveUp"];
}

- (IBAction)stopdown:(id)sender {
    //通过动画标识符取消动画
    [layer removeAnimationForKey:@"moveDown"];
}

- (IBAction)stopup:(id)sender {
    //通过动画标识符取消动画
    [layer removeAnimationForKey:@"moveUp"];
}

- (IBAction)dr:(id)sender {
    CABasicAnimation * downAndRight = [CABasicAnimation animationWithKeyPath:@"position"];
    downAndRight.duration = 5.0;
    //把c结构封装成对象类型
    NSValue * endPoint = [NSValue valueWithCGPoint:CGPointMake(layer.position.x + 100, layer.position.y+100)];
    downAndRight.toValue = endPoint;
    [layer addAnimation:downAndRight forKey:@"downAndRight"];
}

- (IBAction)ul:(id)sender {
    CABasicAnimation * upAndLeft = [CABasicAnimation animationWithKeyPath:@"position"];
    upAndLeft.duration = 5.0;
    NSValue * endPoint = [NSValue valueWithCGPoint:CGPointMake(layer.position.x - 100, layer.position.y-100)];
    upAndLeft.toValue = endPoint;
    [layer addAnimation:upAndLeft forKey:@"upAndLeft"];
}

- (IBAction)stopall:(id)sender {
    //停止该图层上所有动画
    [layer removeAllAnimations];
}

效果如下:



CAAnimation类对象也可以设定它的委托对象,当动画开始与结束时做自定义操作。CAAnimation的delegate属性如下:

可以看到它与其他类的delegate属性有些不同的是,它不需要遵循协议,只要委托对象中有如下函数即可:
- (void)animationDidStart:(CAAnimation *)anim;
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;

下面介绍CAPropertyAnimation的另一个子类CAKeyframeAnimation的用法。
CAKeyframeAnimation可以指定动画执行的路径,能够制作出非常“不规则”的动画。比如沿贝塞尔曲线的动画。
下面就来看看如何来实现贝塞尔曲线动画。
先看头文件:
//
//  PathView.h
//  LearnAnimation
//
//  Created by zg on 15/6/7.
//  Copyright (c) 2015年 zg. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface PathView : UIView{
    CAShapeLayer * shapeLayer;
}

-(void)go;

@end

定义一个圆形图层shapeLayer来执行动画,定义一个执行方法go
再看实现文件:
//
//  PathView.m
//  LearnAnimation
//
//  Created by zg on 15/6/7.
//  Copyright (c) 2015年 zg. All rights reserved.
//

#import "PathView.h"

@implementation PathView


// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    [self drawPath];
    [self drawCircle];
}

//定义角度转弧度宏
#define DEGREES_TO_RADIANS(degrees) ((M_PI * degrees)/180)
//画路径
-(void)drawPath{
    UIBezierPath * path = [UIBezierPath bezierPath];
    path.lineCapStyle = kCGLineCapRound;//路径端点圆状
    [[UIColor blackColor]setStroke];
    [[UIColor blackColor]setFill];
    [path moveToPoint:CGPointMake(0, 100)];
    [path addCurveToPoint:CGPointMake(300, 100) controlPoint1:CGPointMake(75, 25) controlPoint2:CGPointMake(225, 175)];
    [path stroke];
    path.lineWidth = 3;
    [self setNeedsDisplay];
}

//画圆形图层
-(void)drawCircle{
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path addArcWithCenter:CGPointMake(4 , 100) radius:8 startAngle:0 endAngle:DEGREES_TO_RADIANS(360) clockwise:YES];
    [path closePath];
    shapeLayer = [CAShapeLayer layer];
    shapeLayer.path = path.CGPath;
    [self.layer addSublayer:shapeLayer];
}

//执行动画
-(void)go{
    CAKeyframeAnimation * pathAnim = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    pathAnim.duration = 5;
    //生成可变路径
    CGMutablePathRef mutablePath = CGPathCreateMutable();
    //坐标点,相对于当前图层pathLayer自身坐标系
    CGPathMoveToPoint(mutablePath, NULL, 0 , 0);
    CGPathAddCurveToPoint(mutablePath, NULL, 75, -75, 225, 75, 300, 0);
    pathAnim.path = mutablePath;
    [shapeLayer addAnimation:pathAnim forKey:nil];

}

@end

主要解释下实现函数go:
1、因为CAKeyframeAnimation是CAPropertyAnimation的子类,所以也会有animationWithKeyPath的动画声明方法。
2、CAKeyframeAnimation的path属性可以指定动画要执行的路径。
3、要重点说明的是CGMutablePathRef路径的坐标点是相对于执行动画的图层shapeLayer自身坐标系来计算的。
下面看效果:


三度空间的旋转:
layer有一个属性叫sublayerTransform,是渐变属性。通过CABasicAnimation动画来改变sublayerTransform属性,即可实现图层的三度空间旋转。
实现如下:
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self initSubLayer1];
    [self initSubLayer2];
    [self initSubLayer3];
    [self initPerspective];
}

-(void)initPerspective{
    //建立视点
    CATransform3D perspective = CATransform3DIdentity;
    int distance = 150;
    perspective.m34 = -1/distance;
    currentTransform = perspective;
    mContentView.layer.sublayerTransform = currentTransform;
}

-(void)initSubLayer1{
    subLayer1 = [CALayer layer];
    subLayer1.bounds = CGRectMake(0, 0, 100, 100);
    subLayer1.position = CGPointMake(140, 140);
    subLayer1.backgroundColor = [[UIColor blueColor]CGColor];
    subLayer1.cornerRadius = 10;//圆角半径
    subLayer1.borderColor = [[UIColor blackColor]CGColor];
    subLayer1.borderWidth= 2;
    subLayer1.opacity = 0.5;
    [mContentView.layer addSublayer:subLayer1];
}

-(void)initSubLayer2{
    subLayer2 = [CALayer layer];
    subLayer2.bounds = CGRectMake(0, 0, 100, 100);
    subLayer2.position = CGPointMake(150, 150);
    subLayer2.backgroundColor = [[UIColor greenColor]CGColor];
    subLayer2.cornerRadius = 10;//圆角半径
    subLayer2.borderColor = [[UIColor blackColor]CGColor];
    subLayer2.borderWidth= 2;
    subLayer2.opacity = 0.5;
    [mContentView.layer addSublayer:subLayer2];
}

-(void)initSubLayer3{
    subLayer3 = [CALayer layer];
    subLayer3.bounds = CGRectMake(0, 0, 100, 100);
    subLayer3.position = CGPointMake(160, 160);
    subLayer3.backgroundColor = [[UIColor redColor]CGColor];
    subLayer3.cornerRadius = 10;//圆角半径
    subLayer3.borderColor = [[UIColor blackColor]CGColor];
    subLayer3.borderWidth= 2;
    subLayer3.opacity = 0.5;
    [mContentView.layer addSublayer:subLayer3];
}

- (IBAction)rotateZ:(id)sender {
    CABasicAnimation * rotateAnim = [CABasicAnimation animationWithKeyPath:@"sublayerTransform"];
    rotateAnim.fillMode = kCAFillModeForwards;
    rotateAnim.removedOnCompletion = NO;
    
    rotateAnim.duration = 3;
    CATransform3D rotateX3D = CATransform3DRotate(currentTransform, M_PI/6, 0, 0, 1);
    NSValue  * toValue = [NSValue valueWithCATransform3D:rotateX3D];
    rotateAnim.toValue = toValue;
    [mContentView.layer addAnimation:rotateAnim forKey:nil];
    currentTransform = rotateX3D;
}

当执行rotateZ函数可实现如下效果:






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值