您的位置:首页 > 移动开发 > IOS开发

ios动画学习(三)

2015-06-07 15:59 274 查看

使用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函数可实现如下效果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: