动画(Animation) 、 高级动画(Core Animation)
2015-12-15 20:50
411 查看
1 演示UIImage制作的动画
图-1
然后在viewDidLoad方法中使用工厂方法animatedImageNamed:创建UIImage对象image。
最后将imageView的image属性设置为刚才创建的image对象即可。
步骤一:拖放ImageView控件
首先在创建好的Xcode项目的Storyboard中拖放一个ImageView控件,并关联成TRViewController的属性imageView,代码如下所示:
@interface TRViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end
步骤二:使用UIImage生成动画
首先导入图片素材,图片的命名规则是按顺序命名,即每张图片的名称前半部分一样后半部分是序号,例如:0_0_run_00、0_0_run_01、0_0_run_02……
然后在viewDidLoad方法中使用工厂方法animatedImageNamed:创建UIImage对象image,这里需要注意的是imageNamed参数,传入的是图片名称不带序号的部分。
最后将imageView的image属性设置为刚才创建的image对象,代码如下所示:
- (void)viewDidLoad
{
[super viewDidLoad];
UIImage *image = [UIImage animatedImageNamed:@"0_0_run_" duration:2];
self.imageView.image = image;
}
#import "TRViewController.h"
@interface TRViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end
@implementation TRViewController
- (void)viewDidLoad
{
[super viewDidLoad];
UIImage *image = [UIImage animatedImageNamed:@"0_0_run_" duration:2];
self.imageView.image = image;
}
@end
图-2
然后在viewDidLoad方法中创建一个计时器,每隔1/30秒重复调用方法changeAlpha:。
最后实现方法changeAlpha:,每次调用都改变imageView的alpha值。
步骤一:拖放ImageView控件
首先在创建好的Xcode项目的Storyboard中拖放一个和屏幕一样大小的ImageView控件,在右边栏的检查器中给ImageView设置image,并将ImageView设置为TRViewController的属性imageView,代码如下所示:
@interface TRViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end
步骤二:创建计时器
在viewDidLoad方法中创建一个计时器,每隔1/30秒重复调用方法changeAlpha:,代码如下所示:
- (void)viewDidLoad
{
[super viewDidLoad];
[NSTimer scheduledTimerWithTimeInterval:1/FPS target:self selector:@selector(changeAlpha:) userInfo:nil repeats:YES];
}
步骤三:实现changeAlpha:方法
首先定义两个宏FPS用来表示帧率,DURATION用来表示动画时长,在changeAlpha:方法中根据FPS和DURATION计算imageView的alpha值,代码如下所示:
#define FPS 30.0 //帧率
#define DURATION 5.0 //动画时长
//当前值=开始值+当前的帧数*(结束值-开始值)/(帧率*时长)
- (void)changeAlpha:(NSTimer *)timer
{
static NSUInteger count = 0;
count++;
self.imageView.alpha = count * 1.0/(FPS * DURATION);
if (count >= FPS * DURATION) {
[timer invalidate];
}
}
#import "TRViewController.h"
@interface TRViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end
@implementation TRViewController
#define FPS 30.0 //帧率
#define DURATION 5.0 //动画时长
- (void)viewDidLoad
{
[super viewDidLoad];
[NSTimer scheduledTimerWithTimeInterval:1/FPS target:self selector:@selector(changeAlpha:) userInfo:nil repeats:YES];
}
//当前值=开始值+当前的帧数*(结束值-开始值)/(帧率*时长)
- (void)changeAlpha:(NSTimer *)timer
{
static NSUInteger count = 0;
count++;
self.imageView.alpha = count * 1.0/(FPS * DURATION);
if (count >= FPS * DURATION) {
[timer invalidate];
}
}
@end
图-3
然后在Storyboard中拖放一个Button对象,设置标题为Start,并关联成TRViewController的方法start:。
最后在viewDidLoad方法中使用UIView的动画方法实现aircraft和welcomeLabel的入场动画,并在方法start:中使用UIView的动画方法实现飞机的飞行动画。
步骤一:搭建界面
首先在创建好的Xcode项目的Storyboard中拖放一个ImageView控件和一个Label控件,在右边栏的检查器中分别设置ImageView和Label的显示图片和文字,ImageView显示飞机图片,Label显示文字“Welcome To iGame“。
其次将ImageView和Label关联成TRViewController的属性aircraft和welcomeLabel,代码如下所示:
@interface TRViewController ()
@property (weak, nonatomic) IBOutlet UILabel *welcomeLabel;
@property (weak, nonatomic) IBOutlet UIImageView *aircraft;
@end
然后在Storyboard中拖放一个Button对象,设置标题为Start,并关联成TRViewController的方法start:。
最后Storyboard中完成的界面如图-4所示:
图-4
步骤二:使用UIView实现动画
首先在viewDidLoad方法中使用UIView的动画方法实现welcomeLabel的入场动画,welcomeLabel从屏幕的左方进入屏幕,使用UIView的动画方法animateWithDuration: delay: usingSpringWithDamping: initialSpringVelocity: options:增加弹簧效果,代码如下所示:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
//结束位置
CGRect endFrame = self.welcomeLabel.frame;
//开始位置
CGRect startFrame = endFrame;
startFrame.origin.x = - startFrame.size.width;
//welcome的入场动画
self.welcomeLabel.frame = startFrame;
self.welcomeLabel.alpha = 0.1;
[UIView animateWithDuration:5.0 delay:0.3 usingSpringWithDamping:0.1 initialSpringVelocity:5 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.welcomeLabel.frame = endFrame;
self.welcomeLabel.alpha = 1.0;
} completion:^(BOOL finished) {
NSLog(@"动画结束");
}];
}
然后实现飞机的入场动画,飞机从屏幕的下方飞入屏幕,代码如下所示:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
//结束位置
CGRect endFrame = self.welcomeLabel.frame;
//开始位置
CGRect startFrame = endFrame;
startFrame.origin.x = - startFrame.size.width;
//welcome的入场动画
self.welcomeLabel.frame = startFrame;
self.welcomeLabel.alpha = 0.1;
[UIView animateWithDuration:5.0 delay:0.3 usingSpringWithDamping:0.1 initialSpringVelocity:5 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.welcomeLabel.frame = endFrame;
self.welcomeLabel.alpha = 1.0;
} completion:^(BOOL finished) {
NSLog(@"动画结束");
}];
//飞机的入场动画
endFrame = self.aircraft.frame;
startFrame = endFrame;
startFrame.origin.y = self.view.bounds.size.height;
self.aircraft.frame = startFrame;
[UIView animateWithDuration:2.0 animations:^{
self.aircraft.frame = endFrame;
}];
}
最后实现方法start:完成飞机的飞行动画,飞机从屏幕下方飞到屏幕上方,并且在动画结束之后反复在屏幕中飞行,代码如下所示:
- (IBAction)start:(UIButton *)sender
{
CGPoint point = self.aircraft.center;
point.y = 80;
[UIView animateWithDuration:3.0 delay:1.0 options:UIViewAnimationOptionCurveEaseInOut|UIViewAnimationOptionRepeat|UIViewAnimationOptionAutoreverse animations:^{
self.aircraft.center = point;
} completion:^(BOOL finished) {
NSLog(@"动画结束");
}];
}
#import "TRViewController.h"
@interface TRViewController ()
@property (weak, nonatomic) IBOutlet UILabel *welcomeLabel;
@property (weak, nonatomic) IBOutlet UIImageView *aircraft;
@end
@implementation TRViewController
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
//结束位置
CGRect endFrame = self.welcomeLabel.frame;
//开始位置
CGRect startFrame = endFrame;
startFrame.origin.x = - startFrame.size.width;
//welcome的入场动画
self.welcomeLabel.frame = startFrame;
self.welcomeLabel.alpha = 0.1;
[UIView animateWithDuration:5.0 delay:0.3 usingSpringWithDamping:0.1 initialSpringVelocity:5 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.welcomeLabel.frame = endFrame;
self.welcomeLabel.alpha = 1.0;
} completion:^(BOOL finished) {
NSLog(@"动画结束");
}];
//飞机的入场动画
endFrame = self.aircraft.frame;
startFrame = endFrame;
startFrame.origin.y = self.view.bounds.size.height;
self.aircraft.frame = startFrame;
[UIView animateWithDuration:2.0 animations:^{
self.aircraft.frame = endFrame;
}];
}
- (IBAction)start:(UIButton *)sender
{
CGPoint point = self.aircraft.center;
point.y = 80;
[UIView animateWithDuration:3.0 delay:1.0 options:UIViewAnimationOptionCurveEaseInOut|UIViewAnimationOptionRepeat|UIViewAnimationOptionAutoreverse animations:^{
self.aircraft.center = point;
} completion:^(BOOL finished) {
NSLog(@"动画结束");
}];
}
@end
图-5
然后在viewDidLoad方法中设置self.view的layer的背景颜色和圆角。再设置imageView的layer属性,将layer设置完圆角之后要将遮罩打开。
最后在viewDidLoad方法中分别给self.view.layer添加一个无图片的子层和有图片的子层。
步骤一:搭建Storyboard界面
首先在创建好的Xcode项目的Storyboard中拖放一个ImageView控件,在右边栏的检查器中设置ImageView的显示图片,并将ImageView和Label关联成TRViewController的属性imageView,代码如下所示:
@interface TRViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end
步骤二:设置layer属性
首先在viewDidLoad方法中设置self.view的layer的背景颜色和圆角,代码如下所示:
- (void)viewDidLoad
{
[super viewDidLoad];
//设置view的layer
CALayer *layer = self.view.layer;
layer.backgroundColor = [[UIColor orangeColor] CGColor];
layer.cornerRadius = 30.0;
}
运行程序发现背景变成圆角的,如图-6所示:
图-6
其次再设置imageView的layer属性,将layer设置完圆角之后要将遮罩打开,代码如下所示:
- (void)viewDidLoad
{
[super viewDidLoad];
//设置view的layer
CALayer *layer = self.view.layer;
layer.backgroundColor = [[UIColor orangeColor] CGColor];
layer.cornerRadius = 30.0;
//将imageView设置成圆角
self.imageView.layer.cornerRadius = 10.0;
//打开遮罩,否则无效
self.imageView.layer.masksToBounds =YES;
}
然后在viewDidLoad方法中给self.view.layer添加一个无图片的子层,代码如下所示:
- (void)viewDidLoad
{
[super viewDidLoad];
//设置view的layer
CALayer *layer = self.view.layer;
layer.backgroundColor = [[UIColor orangeColor] CGColor];
layer.cornerRadius = 30.0;
//将imageView设置成圆角
self.imageView.layer.cornerRadius = 10.0;
//打开遮罩,否则无效
self.imageView.layer.masksToBounds =YES;
//加子层
CALayer *subLayer = [CALayer layer];
subLayer.backgroundColor = [UIColor purpleColor].CGColor;
subLayer.frame = CGRectMake(30, 200, 100, 120);
//设置阴影
subLayer.shadowColor = [UIColor greenColor].CGColor;
subLayer.shadowOffset = CGSizeMake(2, 2);
subLayer.shadowRadius = 5.0;
subLayer.shadowOpacity = 0.8;
//设置圆角
subLayer.cornerRadius = 10.0;
[layer addSublayer:subLayer];
}
最后在viewDidLoad方法中给self.view.layer添加一个有图片的子层,代码如下所示:
- (void)viewDidLoad
{
[super viewDidLoad];
//设置view的layer
CALayer *layer = self.view.layer;
layer.backgroundColor = [[UIColor orangeColor] CGColor];
layer.cornerRadius = 30.0;
//将imageView设置成圆角
self.imageView.layer.cornerRadius = 10.0;
//打开遮罩,否则无效
self.imageView.layer.masksToBounds =YES;
//加子层
CALayer *subLayer = [CALayer layer];
subLayer.backgroundColor = [UIColor purpleColor].CGColor;
subLayer.frame = CGRectMake(30, 200, 100, 120);
subLayer.shadowColor = [UIColor greenColor].CGColor;
subLayer.shadowOffset = CGSizeMake(2, 2);
subLayer.shadowRadius = 5.0;
subLayer.shadowOpacity = 0.8;
subLayer.cornerRadius = 10.0;
[layer addSublayer:subLayer];
//加有内容的子层
CALayer *imageLayer = [CALayer new];
imageLayer.frame = CGRectMake(180, 300, 100, 120);
//设置层的内容
imageLayer.contents = (id)[UIImage imageNamed:@"d.jpg"].CGImage;
imageLayer.cornerRadius = 10.0;
imageLayer.masksToBounds = YES;
[layer addSublayer:imageLayer];
}
#import "TRViewController.h"
@interface TRViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end
@implementation TRViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//设置view的layer
CALayer *layer = self.view.layer;
layer.backgroundColor = [[UIColor orangeColor] CGColor];
layer.cornerRadius = 30.0;
//将imageView设置成圆角
self.imageView.layer.cornerRadius = 10.0;
//打开遮罩,否则无效
self.imageView.layer.masksToBounds =YES;
//加子层
CALayer *subLayer = [CALayer layer];
subLayer.backgroundColor = [UIColor purpleColor].CGColor;
subLayer.frame = CGRectMake(30, 200, 100, 120);
subLayer.shadowColor = [UIColor greenColor].CGColor;
subLayer.shadowOffset = CGSizeMake(2, 2);
subLayer.shadowRadius = 5.0;
subLayer.shadowOpacity = 0.8;
subLayer.cornerRadius = 10.0;
[layer addSublayer:subLayer];
//加有内容的子层
CALayer *imageLayer = [CALayer new];
imageLayer.frame = CGRectMake(180, 300, 100, 120);
imageLayer.contents = (id)[UIImage imageNamed:@"d.jpg"].CGImage;
imageLayer.cornerRadius = 10.0;
imageLayer.masksToBounds = YES;
[layer addSublayer:imageLayer];
}
@end
图-7
然后在viewDidLoad方法中设置imageView的layer属性,将imageView设置成圆角。
最后实现start:方法,当点击按钮imageView开始执行动画。首先制定一个imageView的动画路径path,是一个UIBezierPath类型,然后分别创建关键帧动画、缩放动画以及透明度改变动画,最后将以上动画放进一个动画群组里面,即CAAnimationGroup类型的group,并将动画添加到imageView的layer中。
步骤一:搭建Storyboard界面
首先在创建好的Xcode项目的Storyboard中拖放一个ImageView控件和一个Button控件,在右边栏的检查器中设置ImageView和Button的属性,并将ImageView关联成TRAnimationViewController的属性imageView,将Button关联成TRAnimationViewController的方法start:,代码如下所示:
@interface TRAnimationViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end
- (IBAction)start:(id)sender
{
}
步骤二:实现imageView的移动动画
首先在viewDidLoad方法中设置imageView的layer属性,将imageView设置成圆角,代码如下所示:
- (void)viewDidLoad
{
[super viewDidLoad];
//设置imageView的layer属性
self.imageView.layer.cornerRadius = 8.0;
self.imageView.layer.masksToBounds = YES;
}
然后实现start:方法,当点击按钮imageView开始执行动画。首先制定一个imageView的动画路径path,是一个UIBezierPath类型,代码如下所示:
- (IBAction)start:(id)sender
{
UIBezierPath *path = [UIBezierPath bezierPath];
[self createCurve:path];
}
- (IBAction)start:(id)sender
{
UIBezierPath *path = [UIBezierPath bezierPath];
[self createCurve:path];
//创建关键帧
CAKeyframeAnimation *moveAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
//设置相关属性
moveAnimation.path = path.CGPath;
moveAnimation.removedOnCompletion = YES;
}
然后创建关键帧动画,并设置相关属性,代码如下所示:
- (IBAction)start:(id)sender
{
UIBezierPath *path = [UIBezierPath bezierPath];
[self createCurve:path];
//创建关键帧
CAKeyframeAnimation *moveAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
//设置相关属性
moveAnimation.path = path.CGPath;
moveAnimation.removedOnCompletion = YES;
}
再创建缩放动画以及透明度改变动画,代码如下所示:
- (IBAction)start:(id)sender
{
UIBezierPath *path = [UIBezierPath bezierPath];
[self createCurve:path];
//创建关键帧
CAKeyframeAnimation *moveAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
//设置相关属性
moveAnimation.path = path.CGPath;
moveAnimation.removedOnCompletion = YES;
//创建缩放动画
CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
scaleAnimation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
scaleAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.1, 0.1, 1.0)];
scaleAnimation.removedOnCompletion = YES;
//创建透明度动画
CABasicAnimation *alphaAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
alphaAnimation.fromValue = @1.0;
alphaAnimation.toValue = @0.0;
alphaAnimation.removedOnCompletion = YES;
}
最后将以上动画放进一个动画群组里面,即CAAnimationGroup类型的group,并将动画添加到imageView的layer中,代码如下所示:
- (IBAction)start:(id)sender
{
UIBezierPath *path = [UIBezierPath bezierPath];
[self createCurve:path];
//创建关键帧
CAKeyframeAnimation *moveAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
//设置相关属性
moveAnimation.path = path.CGPath;
moveAnimation.removedOnCompletion = YES;
//创建缩放动画
CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
scaleAnimation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
scaleAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.1, 0.1, 1.0)];
scaleAnimation.removedOnCompletion = YES;
//创建透明度动画
CABasicAnimation *alphaAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
alphaAnimation.fromValue = @1.0;
alphaAnimation.toValue = @0.0;
alphaAnimation.removedOnCompletion = YES;
//将以上动画放进一个动画组
CAAnimationGroup *group = [CAAnimationGroup animation];
group.animations = @[moveAnimation, scaleAnimation, alphaAnimation];
group.duration = 2.0;
group.delegate = self;
//加入到Layer中
[self.imageView.layer addAnimation:group forKey:nil];
}
实现animation的生命周期方法,当动画结束时将imageView从界面上移除,代码如下所示:
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
[self.imageView removeFromSuperview];
}
#import "TRAnimationViewController.h"
@interface TRAnimationViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end
@implementation TRAnimationViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//设置imageView的layer属性
self.imageView.layer.cornerRadius = 8.0;
self.imageView.layer.masksToBounds = YES;
}
//创建图片运动的曲线
- (void)createCurve:(UIBezierPath *)path
{
[path moveToPoint:self.imageView.center];
CGPoint targetPoint = CGPointMake(self.view.bounds.size.width - self.imageView.frame.size.width - 20, self.view.bounds.size.height - self.imageView.frame.size.height - 20);
CGPoint control1 = CGPointMake(self.view.bounds.size.width - self.imageView.frame.size.width - 20, self.imageView.frame.origin.y);
CGPoint control2 = CGPointMake(self.imageView.frame.origin.x, self.view.bounds.size.height - self.imageView.frame.size.height - 20);
[path addCurveToPoint:targetPoint controlPoint1:control1 controlPoint2:control2];
}
- (IBAction)start:(id)sender
{
UIBezierPath *path = [UIBezierPath bezierPath];
[self createCurve:path];
//创建关键帧
CAKeyframeAnimation *moveAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
//设置相关属性
moveAnimation.path = path.CGPath;
moveAnimation.removedOnCompletion = YES;
//创建缩放动画
CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
scaleAnimation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
scaleAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.1, 0.1, 1.0)];
scaleAnimation.removedOnCompletion = YES;
//创建透明度动画
CABasicAnimation *alphaAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
alphaAnimation.fromValue = @1.0;
alphaAnimation.toValue = @0.0;
alphaAnimation.removedOnCompletion = YES;
//将以上动画放进一个动画组
CAAnimationGroup *group = [CAAnimationGroup animation];
group.animations = @[moveAnimation, scaleAnimation, alphaAnimation];
group.duration = 2.0;
group.delegate = self;
//加入到Layer中
[self.imageView.layer addAnimation:group forKey:nil];
}
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
[self.imageView removeFromSuperview];
}
@end
图-8
再将四个Button关联成TRRotationViewController的四个方法rotationX:、rotationY:、rotationZ:以及rotation:。
然后在viewDidLoad方法中设置imageView的layer属性,将imageView设置成圆角。
最后实现四个Button的动作方法,rotationX:实现功能围绕X轴旋转,rotationY:实现功能围绕Y轴旋转,rotationZ:实现功能围绕Z轴旋转,rotation:实现功能围绕着XYZ轴同时旋转。
步骤一:搭建Storyboard界面
首先在创建好的Xcode项目的Storyboard中拖放一个ImageView控件和四个Button控件,在右边栏的检查器中设置ImageView和Button的属性,并将ImageView关联成TRRotationViewController的属性imageView,代码如下所示:
@interface TRViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end
Storyboard中界面完成的结果如图-9所示:
图-9
步骤二:实现3D旋转动画
首先将四个Button关联成TRRotationViewController的四个方法rotationX:、rotationY:、rotationZ:以及rotation:,
在viewDidLoad方法中设置imageView的layer属性,将imageView设置成圆角,代码如下所示:
- (void)viewDidLoad
{
[super viewDidLoad];
self.imageView.layer.cornerRadius = 8.0;
self.imageView.layer.masksToBounds = YES;
}
然后实现四个Button的动作方法,在rotationX:方法中通过layer的transform属性,实现功能围绕X轴旋转,然后使用类似的方法实现方法rotationY:和rotationZ:,代码如下所示:
- (IBAction)rotationX:(id)sender
{
//创建基本动画
CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
transformAnimation.fromValue = [NSValue valueWithCATransform3D:self.imageView.layer.transform];
//计算目标值
transformAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DRotate(self.imageView.layer.transform, M_PI, 1.0, 0, 0)];
transformAnimation.duration = 3.0;
//将动画添加到imageView的layer上面
[self.imageView.layer addAnimation:transformAnimation forKey:nil];
}
- (IBAction)rotationY:(id)sender
{
CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
transformAnimation.fromValue = [NSValue valueWithCATransform3D:self.imageView.layer.transform];
transformAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DRotate(self.imageView.layer.transform, M_PI, 0.0, 1.0, 0)];
transformAnimation.duration = 3.0;
[self.imageView.layer addAnimation:transformAnimation forKey:nil];
}
- (IBAction)rotationZ:(id)sender
{
CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
transformAnimation.fromValue = [NSValue valueWithCATransform3D:self.imageView.layer.transform];
transformAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DRotate(self.imageView.layer.transform, M_PI, 0.0, 0.0, 1.0)];
transformAnimation.duration = 3.0;
[self.imageView.layer addAnimation:transformAnimation forKey:nil];
}
最后实现rotation:方法,该方法实现功能围绕着XYZ轴同时旋转,代码如下所示:
- (IBAction)rotation:(id)sender
{
CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
transformAnimation.fromValue = [NSValue valueWithCATransform3D:self.imageView.layer.transform];
transformAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DRotate(self.imageView.layer.transform, M_PI, 1.0, 1.0, 1.0)];
transformAnimation.duration = 3.0;
transformAnimation.delegate = self;
[self.imageView.layer addAnimation:transformAnimation forKey:nil];
}
实现animation的生命周期方法,当rotation动画结束时将imageView的transform属性值保持不变,从界面上移除,代码如下所示:
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
self.imageView.layer.transform = CATransform3DRotate(self.imageView.layer.transform, M_PI, 1.0, 1.0, 1.0);
}
#import "TRRotationViewController.h"
@interface TRRotationViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end
@implementation TRRotationViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.imageView.layer.cornerRadius = 8.0;
self.imageView.layer.masksToBounds = YES;
}
- (IBAction)rotationX:(id)sender
{
//创建基本动画
CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
transformAnimation.fromValue = [NSValue valueWithCATransform3D:self.imageView.layer.transform];
//计算目标值
transformAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DRotate(self.imageView.layer.transform, M_PI, 1.0, 0, 0)];
transformAnimation.duration = 3.0;
//将动画添加到imageView的layer上面
[self.imageView.layer addAnimation:transformAnimation forKey:nil];
}
- (IBAction)rotationY:(id)sender
{
CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
transformAnimation.fromValue = [NSValue valueWithCATransform3D:self.imageView.layer.transform];
transformAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DRotate(self.imageView.layer.transform, M_PI, 0.0, 1.0, 0)];
transformAnimation.duration = 3.0;
[self.imageView.layer addAnimation:transformAnimation forKey:nil];
}
- (IBAction)rotationZ:(id)sender
{
CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
transformAnimation.fromValue = [NSValue valueWithCATransform3D:self.imageView.layer.transform];
transformAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DRotate(self.imageView.layer.transform, M_PI, 0.0, 0.0, 1.0)];
transformAnimation.duration = 3.0;
[self.imageView.layer addAnimation:transformAnimation forKey:nil];
}
- (IBAction)rotation:(id)sender
{
CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
transformAnimation.fromValue = [NSValue valueWithCATransform3D:self.imageView.layer.transform];
transformAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DRotate(self.imageView.layer.transform, M_PI, 1.0, 1.0, 1.0)];
transformAnimation.duration = 3.0;
transformAnimation.delegate = self;
[self.imageView.layer addAnimation:transformAnimation forKey:nil];
}
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
self.imageView.layer.transform = CATransform3DRotate(self.imageView.layer.transform, M_PI, 1.0, 1.0, 1.0);
}
@end
1.1 问题
UIImage动画是IOS提供的最基本的动画,通常用于制作一些小型的动画,本案例使用UIImage制作一个小狗跑动的动画,如图-1所示:图-1
1.2 方案
首先在创建好的Xcode项目的Storyboard中拖放一个ImageView控件,并关联成TRViewController的属性imageView。然后在viewDidLoad方法中使用工厂方法animatedImageNamed:创建UIImage对象image。
最后将imageView的image属性设置为刚才创建的image对象即可。
1.3 步骤
实现此案例需要按照如下步骤进行。步骤一:拖放ImageView控件
首先在创建好的Xcode项目的Storyboard中拖放一个ImageView控件,并关联成TRViewController的属性imageView,代码如下所示:
@interface TRViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end
步骤二:使用UIImage生成动画
首先导入图片素材,图片的命名规则是按顺序命名,即每张图片的名称前半部分一样后半部分是序号,例如:0_0_run_00、0_0_run_01、0_0_run_02……
然后在viewDidLoad方法中使用工厂方法animatedImageNamed:创建UIImage对象image,这里需要注意的是imageNamed参数,传入的是图片名称不带序号的部分。
最后将imageView的image属性设置为刚才创建的image对象,代码如下所示:
- (void)viewDidLoad
{
[super viewDidLoad];
UIImage *image = [UIImage animatedImageNamed:@"0_0_run_" duration:2];
self.imageView.image = image;
}
1.4 完整代码
本案例中,TRViewController.m文件中的完整代码如下所示:#import "TRViewController.h"
@interface TRViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end
@implementation TRViewController
- (void)viewDidLoad
{
[super viewDidLoad];
UIImage *image = [UIImage animatedImageNamed:@"0_0_run_" duration:2];
self.imageView.image = image;
}
@end
2 使用NSTimer做一个图片淡入的效果
2.1 问题
NSTimer是一个计时器类,用于定时向指定对象发送消息,本案例使用NSTimer制作一个图片淡入的效果,即每隔一定的时间改变图片的alpha值,如图-2所示:图-2
2.2 方案
首先在创建好的Xcode项目的Storyboard中拖放一个和屏幕一样大小的ImageView控件,并将ImageView设置为TRViewController的属性imageView。然后在viewDidLoad方法中创建一个计时器,每隔1/30秒重复调用方法changeAlpha:。
最后实现方法changeAlpha:,每次调用都改变imageView的alpha值。
2.3 步骤
实现此案例需要按照如下步骤进行。步骤一:拖放ImageView控件
首先在创建好的Xcode项目的Storyboard中拖放一个和屏幕一样大小的ImageView控件,在右边栏的检查器中给ImageView设置image,并将ImageView设置为TRViewController的属性imageView,代码如下所示:
@interface TRViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end
步骤二:创建计时器
在viewDidLoad方法中创建一个计时器,每隔1/30秒重复调用方法changeAlpha:,代码如下所示:
- (void)viewDidLoad
{
[super viewDidLoad];
[NSTimer scheduledTimerWithTimeInterval:1/FPS target:self selector:@selector(changeAlpha:) userInfo:nil repeats:YES];
}
步骤三:实现changeAlpha:方法
首先定义两个宏FPS用来表示帧率,DURATION用来表示动画时长,在changeAlpha:方法中根据FPS和DURATION计算imageView的alpha值,代码如下所示:
#define FPS 30.0 //帧率
#define DURATION 5.0 //动画时长
//当前值=开始值+当前的帧数*(结束值-开始值)/(帧率*时长)
- (void)changeAlpha:(NSTimer *)timer
{
static NSUInteger count = 0;
count++;
self.imageView.alpha = count * 1.0/(FPS * DURATION);
if (count >= FPS * DURATION) {
[timer invalidate];
}
}
2.4 完整代码
本案例中,TRViewController.m文件中的完整代码如下所示:#import "TRViewController.h"
@interface TRViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end
@implementation TRViewController
#define FPS 30.0 //帧率
#define DURATION 5.0 //动画时长
- (void)viewDidLoad
{
[super viewDidLoad];
[NSTimer scheduledTimerWithTimeInterval:1/FPS target:self selector:@selector(changeAlpha:) userInfo:nil repeats:YES];
}
//当前值=开始值+当前的帧数*(结束值-开始值)/(帧率*时长)
- (void)changeAlpha:(NSTimer *)timer
{
static NSUInteger count = 0;
count++;
self.imageView.alpha = count * 1.0/(FPS * DURATION);
if (count >= FPS * DURATION) {
[timer invalidate];
}
}
@end
3 使用UIView制作动画
3.1 问题
UIView动画是UIKit提供专门制作动画的API,其本质是对CoreAnimation的封装,使用UIView可以轻松方便的实现动画,不需要经过任何计算,本案例使用UIView制作一个飞机移动的动画,如图-3所示:图-3
3.2 方案
首先在创建好的Xcode项目的Storyboard中拖放一个ImageView控件和一个Label控件,在右边栏的检查器中分别设置ImageView和Label的显示图片和文字,ImageView显示飞机图片,Label显示文字“Welcome To iGame“,并将ImageView和Label关联成TRViewController的属性aircraft和welcomeLabel。然后在Storyboard中拖放一个Button对象,设置标题为Start,并关联成TRViewController的方法start:。
最后在viewDidLoad方法中使用UIView的动画方法实现aircraft和welcomeLabel的入场动画,并在方法start:中使用UIView的动画方法实现飞机的飞行动画。
3.3 步骤
实现此案例需要按照如下步骤进行。步骤一:搭建界面
首先在创建好的Xcode项目的Storyboard中拖放一个ImageView控件和一个Label控件,在右边栏的检查器中分别设置ImageView和Label的显示图片和文字,ImageView显示飞机图片,Label显示文字“Welcome To iGame“。
其次将ImageView和Label关联成TRViewController的属性aircraft和welcomeLabel,代码如下所示:
@interface TRViewController ()
@property (weak, nonatomic) IBOutlet UILabel *welcomeLabel;
@property (weak, nonatomic) IBOutlet UIImageView *aircraft;
@end
然后在Storyboard中拖放一个Button对象,设置标题为Start,并关联成TRViewController的方法start:。
最后Storyboard中完成的界面如图-4所示:
图-4
步骤二:使用UIView实现动画
首先在viewDidLoad方法中使用UIView的动画方法实现welcomeLabel的入场动画,welcomeLabel从屏幕的左方进入屏幕,使用UIView的动画方法animateWithDuration: delay: usingSpringWithDamping: initialSpringVelocity: options:增加弹簧效果,代码如下所示:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
//结束位置
CGRect endFrame = self.welcomeLabel.frame;
//开始位置
CGRect startFrame = endFrame;
startFrame.origin.x = - startFrame.size.width;
//welcome的入场动画
self.welcomeLabel.frame = startFrame;
self.welcomeLabel.alpha = 0.1;
[UIView animateWithDuration:5.0 delay:0.3 usingSpringWithDamping:0.1 initialSpringVelocity:5 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.welcomeLabel.frame = endFrame;
self.welcomeLabel.alpha = 1.0;
} completion:^(BOOL finished) {
NSLog(@"动画结束");
}];
}
然后实现飞机的入场动画,飞机从屏幕的下方飞入屏幕,代码如下所示:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
//结束位置
CGRect endFrame = self.welcomeLabel.frame;
//开始位置
CGRect startFrame = endFrame;
startFrame.origin.x = - startFrame.size.width;
//welcome的入场动画
self.welcomeLabel.frame = startFrame;
self.welcomeLabel.alpha = 0.1;
[UIView animateWithDuration:5.0 delay:0.3 usingSpringWithDamping:0.1 initialSpringVelocity:5 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.welcomeLabel.frame = endFrame;
self.welcomeLabel.alpha = 1.0;
} completion:^(BOOL finished) {
NSLog(@"动画结束");
}];
//飞机的入场动画
endFrame = self.aircraft.frame;
startFrame = endFrame;
startFrame.origin.y = self.view.bounds.size.height;
self.aircraft.frame = startFrame;
[UIView animateWithDuration:2.0 animations:^{
self.aircraft.frame = endFrame;
}];
}
最后实现方法start:完成飞机的飞行动画,飞机从屏幕下方飞到屏幕上方,并且在动画结束之后反复在屏幕中飞行,代码如下所示:
- (IBAction)start:(UIButton *)sender
{
CGPoint point = self.aircraft.center;
point.y = 80;
[UIView animateWithDuration:3.0 delay:1.0 options:UIViewAnimationOptionCurveEaseInOut|UIViewAnimationOptionRepeat|UIViewAnimationOptionAutoreverse animations:^{
self.aircraft.center = point;
} completion:^(BOOL finished) {
NSLog(@"动画结束");
}];
}
3.4 完整代码
本案例中,TRViewController.m文件中的完整代码如下所示:#import "TRViewController.h"
@interface TRViewController ()
@property (weak, nonatomic) IBOutlet UILabel *welcomeLabel;
@property (weak, nonatomic) IBOutlet UIImageView *aircraft;
@end
@implementation TRViewController
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
//结束位置
CGRect endFrame = self.welcomeLabel.frame;
//开始位置
CGRect startFrame = endFrame;
startFrame.origin.x = - startFrame.size.width;
//welcome的入场动画
self.welcomeLabel.frame = startFrame;
self.welcomeLabel.alpha = 0.1;
[UIView animateWithDuration:5.0 delay:0.3 usingSpringWithDamping:0.1 initialSpringVelocity:5 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.welcomeLabel.frame = endFrame;
self.welcomeLabel.alpha = 1.0;
} completion:^(BOOL finished) {
NSLog(@"动画结束");
}];
//飞机的入场动画
endFrame = self.aircraft.frame;
startFrame = endFrame;
startFrame.origin.y = self.view.bounds.size.height;
self.aircraft.frame = startFrame;
[UIView animateWithDuration:2.0 animations:^{
self.aircraft.frame = endFrame;
}];
}
- (IBAction)start:(UIButton *)sender
{
CGPoint point = self.aircraft.center;
point.y = 80;
[UIView animateWithDuration:3.0 delay:1.0 options:UIViewAnimationOptionCurveEaseInOut|UIViewAnimationOptionRepeat|UIViewAnimationOptionAutoreverse animations:^{
self.aircraft.center = point;
} completion:^(BOOL finished) {
NSLog(@"动画结束");
}];
}
@end
4 CALayer的简单应用
4.1 问题
任何UIView及子类对象都有一个属性叫layer,此属性就是UIView的CoreAnimation层,类型是CALayer,本案例演示CALayer如何使用,如图-5所示:图-5
4.2 方案
首先在创建好的Xcode项目的Storyboard中拖放一个ImageView控件,在右边栏的检查器中设置ImageView的显示图片,并将ImageView和Label关联成TRViewController的属性imageView。然后在viewDidLoad方法中设置self.view的layer的背景颜色和圆角。再设置imageView的layer属性,将layer设置完圆角之后要将遮罩打开。
最后在viewDidLoad方法中分别给self.view.layer添加一个无图片的子层和有图片的子层。
4.3 步骤
实现此案例需要按照如下步骤进行。步骤一:搭建Storyboard界面
首先在创建好的Xcode项目的Storyboard中拖放一个ImageView控件,在右边栏的检查器中设置ImageView的显示图片,并将ImageView和Label关联成TRViewController的属性imageView,代码如下所示:
@interface TRViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end
步骤二:设置layer属性
首先在viewDidLoad方法中设置self.view的layer的背景颜色和圆角,代码如下所示:
- (void)viewDidLoad
{
[super viewDidLoad];
//设置view的layer
CALayer *layer = self.view.layer;
layer.backgroundColor = [[UIColor orangeColor] CGColor];
layer.cornerRadius = 30.0;
}
运行程序发现背景变成圆角的,如图-6所示:
图-6
其次再设置imageView的layer属性,将layer设置完圆角之后要将遮罩打开,代码如下所示:
- (void)viewDidLoad
{
[super viewDidLoad];
//设置view的layer
CALayer *layer = self.view.layer;
layer.backgroundColor = [[UIColor orangeColor] CGColor];
layer.cornerRadius = 30.0;
//将imageView设置成圆角
self.imageView.layer.cornerRadius = 10.0;
//打开遮罩,否则无效
self.imageView.layer.masksToBounds =YES;
}
然后在viewDidLoad方法中给self.view.layer添加一个无图片的子层,代码如下所示:
- (void)viewDidLoad
{
[super viewDidLoad];
//设置view的layer
CALayer *layer = self.view.layer;
layer.backgroundColor = [[UIColor orangeColor] CGColor];
layer.cornerRadius = 30.0;
//将imageView设置成圆角
self.imageView.layer.cornerRadius = 10.0;
//打开遮罩,否则无效
self.imageView.layer.masksToBounds =YES;
//加子层
CALayer *subLayer = [CALayer layer];
subLayer.backgroundColor = [UIColor purpleColor].CGColor;
subLayer.frame = CGRectMake(30, 200, 100, 120);
//设置阴影
subLayer.shadowColor = [UIColor greenColor].CGColor;
subLayer.shadowOffset = CGSizeMake(2, 2);
subLayer.shadowRadius = 5.0;
subLayer.shadowOpacity = 0.8;
//设置圆角
subLayer.cornerRadius = 10.0;
[layer addSublayer:subLayer];
}
最后在viewDidLoad方法中给self.view.layer添加一个有图片的子层,代码如下所示:
- (void)viewDidLoad
{
[super viewDidLoad];
//设置view的layer
CALayer *layer = self.view.layer;
layer.backgroundColor = [[UIColor orangeColor] CGColor];
layer.cornerRadius = 30.0;
//将imageView设置成圆角
self.imageView.layer.cornerRadius = 10.0;
//打开遮罩,否则无效
self.imageView.layer.masksToBounds =YES;
//加子层
CALayer *subLayer = [CALayer layer];
subLayer.backgroundColor = [UIColor purpleColor].CGColor;
subLayer.frame = CGRectMake(30, 200, 100, 120);
subLayer.shadowColor = [UIColor greenColor].CGColor;
subLayer.shadowOffset = CGSizeMake(2, 2);
subLayer.shadowRadius = 5.0;
subLayer.shadowOpacity = 0.8;
subLayer.cornerRadius = 10.0;
[layer addSublayer:subLayer];
//加有内容的子层
CALayer *imageLayer = [CALayer new];
imageLayer.frame = CGRectMake(180, 300, 100, 120);
//设置层的内容
imageLayer.contents = (id)[UIImage imageNamed:@"d.jpg"].CGImage;
imageLayer.cornerRadius = 10.0;
imageLayer.masksToBounds = YES;
[layer addSublayer:imageLayer];
}
4.4 完整代码
本案例中,TRViewController.m文件中的完整代码如下所示:#import "TRViewController.h"
@interface TRViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end
@implementation TRViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//设置view的layer
CALayer *layer = self.view.layer;
layer.backgroundColor = [[UIColor orangeColor] CGColor];
layer.cornerRadius = 30.0;
//将imageView设置成圆角
self.imageView.layer.cornerRadius = 10.0;
//打开遮罩,否则无效
self.imageView.layer.masksToBounds =YES;
//加子层
CALayer *subLayer = [CALayer layer];
subLayer.backgroundColor = [UIColor purpleColor].CGColor;
subLayer.frame = CGRectMake(30, 200, 100, 120);
subLayer.shadowColor = [UIColor greenColor].CGColor;
subLayer.shadowOffset = CGSizeMake(2, 2);
subLayer.shadowRadius = 5.0;
subLayer.shadowOpacity = 0.8;
subLayer.cornerRadius = 10.0;
[layer addSublayer:subLayer];
//加有内容的子层
CALayer *imageLayer = [CALayer new];
imageLayer.frame = CGRectMake(180, 300, 100, 120);
imageLayer.contents = (id)[UIImage imageNamed:@"d.jpg"].CGImage;
imageLayer.cornerRadius = 10.0;
imageLayer.masksToBounds = YES;
[layer addSublayer:imageLayer];
}
@end
5 使用CoreAnimation制作动画
5.1 问题
CoreAnimation是一个图形渲染和动画的底层框架,能够提供更多更强大的图形渲染显示效果。本案例使用CoreAnimation的关键帧动画方法和基础动画方法制作动画,如图-7所示:图-7
5.2 方案
首先在创建好的Xcode项目的Storyboard中拖放一个ImageView控件和一个Button控件,在右边栏的检查器中设置ImageView和Button的属性,并将ImageView关联成TRAnimationViewController的属性imageView,将Button关联成TRAnimationViewController的方法start:。然后在viewDidLoad方法中设置imageView的layer属性,将imageView设置成圆角。
最后实现start:方法,当点击按钮imageView开始执行动画。首先制定一个imageView的动画路径path,是一个UIBezierPath类型,然后分别创建关键帧动画、缩放动画以及透明度改变动画,最后将以上动画放进一个动画群组里面,即CAAnimationGroup类型的group,并将动画添加到imageView的layer中。
5.3 步骤
实现此案例需要按照如下步骤进行。步骤一:搭建Storyboard界面
首先在创建好的Xcode项目的Storyboard中拖放一个ImageView控件和一个Button控件,在右边栏的检查器中设置ImageView和Button的属性,并将ImageView关联成TRAnimationViewController的属性imageView,将Button关联成TRAnimationViewController的方法start:,代码如下所示:
@interface TRAnimationViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end
- (IBAction)start:(id)sender
{
}
步骤二:实现imageView的移动动画
首先在viewDidLoad方法中设置imageView的layer属性,将imageView设置成圆角,代码如下所示:
- (void)viewDidLoad
{
[super viewDidLoad];
//设置imageView的layer属性
self.imageView.layer.cornerRadius = 8.0;
self.imageView.layer.masksToBounds = YES;
}
然后实现start:方法,当点击按钮imageView开始执行动画。首先制定一个imageView的动画路径path,是一个UIBezierPath类型,代码如下所示:
- (IBAction)start:(id)sender
{
UIBezierPath *path = [UIBezierPath bezierPath];
[self createCurve:path];
}
- (IBAction)start:(id)sender
{
UIBezierPath *path = [UIBezierPath bezierPath];
[self createCurve:path];
//创建关键帧
CAKeyframeAnimation *moveAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
//设置相关属性
moveAnimation.path = path.CGPath;
moveAnimation.removedOnCompletion = YES;
}
然后创建关键帧动画,并设置相关属性,代码如下所示:
- (IBAction)start:(id)sender
{
UIBezierPath *path = [UIBezierPath bezierPath];
[self createCurve:path];
//创建关键帧
CAKeyframeAnimation *moveAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
//设置相关属性
moveAnimation.path = path.CGPath;
moveAnimation.removedOnCompletion = YES;
}
再创建缩放动画以及透明度改变动画,代码如下所示:
- (IBAction)start:(id)sender
{
UIBezierPath *path = [UIBezierPath bezierPath];
[self createCurve:path];
//创建关键帧
CAKeyframeAnimation *moveAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
//设置相关属性
moveAnimation.path = path.CGPath;
moveAnimation.removedOnCompletion = YES;
//创建缩放动画
CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
scaleAnimation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
scaleAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.1, 0.1, 1.0)];
scaleAnimation.removedOnCompletion = YES;
//创建透明度动画
CABasicAnimation *alphaAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
alphaAnimation.fromValue = @1.0;
alphaAnimation.toValue = @0.0;
alphaAnimation.removedOnCompletion = YES;
}
最后将以上动画放进一个动画群组里面,即CAAnimationGroup类型的group,并将动画添加到imageView的layer中,代码如下所示:
- (IBAction)start:(id)sender
{
UIBezierPath *path = [UIBezierPath bezierPath];
[self createCurve:path];
//创建关键帧
CAKeyframeAnimation *moveAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
//设置相关属性
moveAnimation.path = path.CGPath;
moveAnimation.removedOnCompletion = YES;
//创建缩放动画
CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
scaleAnimation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
scaleAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.1, 0.1, 1.0)];
scaleAnimation.removedOnCompletion = YES;
//创建透明度动画
CABasicAnimation *alphaAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
alphaAnimation.fromValue = @1.0;
alphaAnimation.toValue = @0.0;
alphaAnimation.removedOnCompletion = YES;
//将以上动画放进一个动画组
CAAnimationGroup *group = [CAAnimationGroup animation];
group.animations = @[moveAnimation, scaleAnimation, alphaAnimation];
group.duration = 2.0;
group.delegate = self;
//加入到Layer中
[self.imageView.layer addAnimation:group forKey:nil];
}
实现animation的生命周期方法,当动画结束时将imageView从界面上移除,代码如下所示:
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
[self.imageView removeFromSuperview];
}
5.4 完整代码
本案例中,TRAnimationViewController.m文件中的完整代码如下所示:#import "TRAnimationViewController.h"
@interface TRAnimationViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end
@implementation TRAnimationViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//设置imageView的layer属性
self.imageView.layer.cornerRadius = 8.0;
self.imageView.layer.masksToBounds = YES;
}
//创建图片运动的曲线
- (void)createCurve:(UIBezierPath *)path
{
[path moveToPoint:self.imageView.center];
CGPoint targetPoint = CGPointMake(self.view.bounds.size.width - self.imageView.frame.size.width - 20, self.view.bounds.size.height - self.imageView.frame.size.height - 20);
CGPoint control1 = CGPointMake(self.view.bounds.size.width - self.imageView.frame.size.width - 20, self.imageView.frame.origin.y);
CGPoint control2 = CGPointMake(self.imageView.frame.origin.x, self.view.bounds.size.height - self.imageView.frame.size.height - 20);
[path addCurveToPoint:targetPoint controlPoint1:control1 controlPoint2:control2];
}
- (IBAction)start:(id)sender
{
UIBezierPath *path = [UIBezierPath bezierPath];
[self createCurve:path];
//创建关键帧
CAKeyframeAnimation *moveAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
//设置相关属性
moveAnimation.path = path.CGPath;
moveAnimation.removedOnCompletion = YES;
//创建缩放动画
CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
scaleAnimation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
scaleAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.1, 0.1, 1.0)];
scaleAnimation.removedOnCompletion = YES;
//创建透明度动画
CABasicAnimation *alphaAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
alphaAnimation.fromValue = @1.0;
alphaAnimation.toValue = @0.0;
alphaAnimation.removedOnCompletion = YES;
//将以上动画放进一个动画组
CAAnimationGroup *group = [CAAnimationGroup animation];
group.animations = @[moveAnimation, scaleAnimation, alphaAnimation];
group.duration = 2.0;
group.delegate = self;
//加入到Layer中
[self.imageView.layer addAnimation:group forKey:nil];
}
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
[self.imageView removeFromSuperview];
}
@end
6 使用CATransform3D制作3D动画
6.1 问题
CATransform3D是一个结构体,是一个4x4的矩阵,用于描述一个3D图形的变形,包括旋转、缩放以及位移,本案例使用CATransform3D制作3D旋转动画,如图-8所示:图-8
6.2 方案
首先在创建好的Xcode项目的Storyboard中拖放一个ImageView控件和四个Button控件,在右边栏的检查器中设置ImageView和Button的属性,并将ImageView关联成TRRotationViewController的属性imageView。再将四个Button关联成TRRotationViewController的四个方法rotationX:、rotationY:、rotationZ:以及rotation:。
然后在viewDidLoad方法中设置imageView的layer属性,将imageView设置成圆角。
最后实现四个Button的动作方法,rotationX:实现功能围绕X轴旋转,rotationY:实现功能围绕Y轴旋转,rotationZ:实现功能围绕Z轴旋转,rotation:实现功能围绕着XYZ轴同时旋转。
6.3 步骤
实现此案例需要按照如下步骤进行。步骤一:搭建Storyboard界面
首先在创建好的Xcode项目的Storyboard中拖放一个ImageView控件和四个Button控件,在右边栏的检查器中设置ImageView和Button的属性,并将ImageView关联成TRRotationViewController的属性imageView,代码如下所示:
@interface TRViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end
Storyboard中界面完成的结果如图-9所示:
图-9
步骤二:实现3D旋转动画
首先将四个Button关联成TRRotationViewController的四个方法rotationX:、rotationY:、rotationZ:以及rotation:,
在viewDidLoad方法中设置imageView的layer属性,将imageView设置成圆角,代码如下所示:
- (void)viewDidLoad
{
[super viewDidLoad];
self.imageView.layer.cornerRadius = 8.0;
self.imageView.layer.masksToBounds = YES;
}
然后实现四个Button的动作方法,在rotationX:方法中通过layer的transform属性,实现功能围绕X轴旋转,然后使用类似的方法实现方法rotationY:和rotationZ:,代码如下所示:
- (IBAction)rotationX:(id)sender
{
//创建基本动画
CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
transformAnimation.fromValue = [NSValue valueWithCATransform3D:self.imageView.layer.transform];
//计算目标值
transformAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DRotate(self.imageView.layer.transform, M_PI, 1.0, 0, 0)];
transformAnimation.duration = 3.0;
//将动画添加到imageView的layer上面
[self.imageView.layer addAnimation:transformAnimation forKey:nil];
}
- (IBAction)rotationY:(id)sender
{
CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
transformAnimation.fromValue = [NSValue valueWithCATransform3D:self.imageView.layer.transform];
transformAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DRotate(self.imageView.layer.transform, M_PI, 0.0, 1.0, 0)];
transformAnimation.duration = 3.0;
[self.imageView.layer addAnimation:transformAnimation forKey:nil];
}
- (IBAction)rotationZ:(id)sender
{
CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
transformAnimation.fromValue = [NSValue valueWithCATransform3D:self.imageView.layer.transform];
transformAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DRotate(self.imageView.layer.transform, M_PI, 0.0, 0.0, 1.0)];
transformAnimation.duration = 3.0;
[self.imageView.layer addAnimation:transformAnimation forKey:nil];
}
最后实现rotation:方法,该方法实现功能围绕着XYZ轴同时旋转,代码如下所示:
- (IBAction)rotation:(id)sender
{
CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
transformAnimation.fromValue = [NSValue valueWithCATransform3D:self.imageView.layer.transform];
transformAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DRotate(self.imageView.layer.transform, M_PI, 1.0, 1.0, 1.0)];
transformAnimation.duration = 3.0;
transformAnimation.delegate = self;
[self.imageView.layer addAnimation:transformAnimation forKey:nil];
}
实现animation的生命周期方法,当rotation动画结束时将imageView的transform属性值保持不变,从界面上移除,代码如下所示:
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
self.imageView.layer.transform = CATransform3DRotate(self.imageView.layer.transform, M_PI, 1.0, 1.0, 1.0);
}
6.4 完整代码
本案例中,TRRotationViewController.m文件中的完整代码如下所示:#import "TRRotationViewController.h"
@interface TRRotationViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end
@implementation TRRotationViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.imageView.layer.cornerRadius = 8.0;
self.imageView.layer.masksToBounds = YES;
}
- (IBAction)rotationX:(id)sender
{
//创建基本动画
CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
transformAnimation.fromValue = [NSValue valueWithCATransform3D:self.imageView.layer.transform];
//计算目标值
transformAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DRotate(self.imageView.layer.transform, M_PI, 1.0, 0, 0)];
transformAnimation.duration = 3.0;
//将动画添加到imageView的layer上面
[self.imageView.layer addAnimation:transformAnimation forKey:nil];
}
- (IBAction)rotationY:(id)sender
{
CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
transformAnimation.fromValue = [NSValue valueWithCATransform3D:self.imageView.layer.transform];
transformAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DRotate(self.imageView.layer.transform, M_PI, 0.0, 1.0, 0)];
transformAnimation.duration = 3.0;
[self.imageView.layer addAnimation:transformAnimation forKey:nil];
}
- (IBAction)rotationZ:(id)sender
{
CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
transformAnimation.fromValue = [NSValue valueWithCATransform3D:self.imageView.layer.transform];
transformAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DRotate(self.imageView.layer.transform, M_PI, 0.0, 0.0, 1.0)];
transformAnimation.duration = 3.0;
[self.imageView.layer addAnimation:transformAnimation forKey:nil];
}
- (IBAction)rotation:(id)sender
{
CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
transformAnimation.fromValue = [NSValue valueWithCATransform3D:self.imageView.layer.transform];
transformAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DRotate(self.imageView.layer.transform, M_PI, 1.0, 1.0, 1.0)];
transformAnimation.duration = 3.0;
transformAnimation.delegate = self;
[self.imageView.layer addAnimation:transformAnimation forKey:nil];
}
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
self.imageView.layer.transform = CATransform3DRotate(self.imageView.layer.transform, M_PI, 1.0, 1.0, 1.0);
}
@end
相关文章推荐
- offload error: cannot find offload entry解决办法
- offload error: cannot find offload entry解决办法
- 实战c++中的vector系列--构造、operator=和assign区别
- 实战c++中的vector系列--构造、operator=和assign区别
- 关于基类析构函数的问题 http://bbs.csdn.net/topics/390543618
- 使用FreeImage写通用图像加载器
- Oracle执行计划
- win10 python nltk安装
- Mousetrap - Keyboard shortcuts in Javascript
- DOM 对象控制 HTML
- oracle视图
- pAdTy_4 构建有联系人和签署的应用程序
- UI06_UIPageControl
- Valid Sudoku
- HDU 1180 诡异的楼梯 BFS
- 周记——20151214
- Maven之Hello World入门实例
- 动画(Animation) 、 高级动画(Core Animation)
- OpenGL中的矩阵相乘
- <LeetCode OJ> (1 / 15 / 16 / 18) NSum问题集合