iOS能够实现动画的方式:
- UIView基础实现方式一
- UIView基础实现方式二
- CoreAnimation实现方式
动画的效果:
- 传达状态
- 提高用户对直接操作的感知
- 帮助用户可视化操作的结果
GIF和刷新菊花
#pragma mark ---GIF
- (
void
)playGIF{
NSMutableArray *dataArray = [ NSMutableArray array ];
for ( int i = 0; i < 43; i++) {
UIImage *image = [ UIImage imageNamed :[ NSString stringWithFormat : @"ima_%d.tiff" , i]];
[dataArray addObject :image];
}
UIImageView *imageView = [[ UIImageView alloc ] initWithFrame : CGRectMake (50, 50, 200, 200)];
// 播放时长
imageView. animationDuration = 3;
// 播放的数组
imageView. animationImages = dataArray;
// 重复次数
imageView. animationRepeatCount = -1;
[ self . view addSubview :imageView];
// 开始
[imageView startAnimating ];
NSMutableArray *dataArray = [ NSMutableArray array ];
for ( int i = 0; i < 43; i++) {
UIImage *image = [ UIImage imageNamed :[ NSString stringWithFormat : @"ima_%d.tiff" , i]];
[dataArray addObject :image];
}
UIImageView *imageView = [[ UIImageView alloc ] initWithFrame : CGRectMake (50, 50, 200, 200)];
// 播放时长
imageView. animationDuration = 3;
// 播放的数组
imageView. animationImages = dataArray;
// 重复次数
imageView. animationRepeatCount = -1;
[ self . view addSubview :imageView];
// 开始
[imageView startAnimating ];
}
#pragma mark ---
菊花
//加载时候旋转的菊花
@property
(
nonatomic
,
strong
)
UIActivityIndicatorView
*indicatorView;
- (
void
)playJvHua{
//初始化,并且设置style(枚举),bounds系统固定
self
.
indicatorView
= [[
UIActivityIndicatorView
alloc
]
initWithActivityIndicatorStyle
:(
UIActivityIndicatorViewStyleWhite
)];
self . indicatorView . center = self . view . center ;
self . indicatorView . color = [ UIColor colorWithRed : arc4random () % 256 / 255.0 green : arc4random () % 256 / 255.0 blue : arc4random () % 256 / 255.0 alpha : 1];
[ self . indicatorView startAnimating ];
[ self . view addSubview : self . indicatorView ];
self . indicatorView . center = self . view . center ;
self . indicatorView . color = [ UIColor colorWithRed : arc4random () % 256 / 255.0 green : arc4random () % 256 / 255.0 blue : arc4random () % 256 / 255.0 alpha : 1];
[ self . indicatorView startAnimating ];
[ self . view addSubview : self . indicatorView ];
}
UIView基础动画一
- UIKit直接将动画继承到UIView类中, 当内部的一些属性发生改变时, UIView将为这些改变提供动画支持.
- 执行动画的工作由UIView类自动完成, 但希望在执行动画时通知视图, 为此需要将改变属性的代码放在[UIView beginAnimations: nil context: nil] 和 [UIView commitAnimations] 之间.
#import
"ViewController.h"
@interface ViewController ()
@property ( nonatomic , strong ) UIView *textView;
@end
@implementation ViewController
- ( void )viewDidLoad {
[ super viewDidLoad ];
_textView = [[ UIView alloc ] initWithFrame : CGRectMake (100, 100, 100, 100)];
_textView . backgroundColor = [ UIColor cyanColor ];
[ self . view addSubview : _textView ];
[ self textViewAction ];
[ self uiViewBlock ];
@interface ViewController ()
@property ( nonatomic , strong ) UIView *textView;
@end
@implementation ViewController
- ( void )viewDidLoad {
[ super viewDidLoad ];
_textView = [[ UIView alloc ] initWithFrame : CGRectMake (100, 100, 100, 100)];
_textView . backgroundColor = [ UIColor cyanColor ];
[ self . view addSubview : _textView ];
[ self textViewAction ];
[ self uiViewBlock ];
[self
keyframeAnimation
];
}
#pragma mark --- 块动画
- ( void )textViewAction{
// 开始执行动画
// 参数 1 : 动画名字
// 参数 2 : 动画的设置 保留字段
[ UIView beginAnimations : @"oneAnimation" context : nil ];
// 从当前的状态开始执行动画 ( 效果不明显 )
[ UIView setAnimationBeginsFromCurrentState : YES ];
// 动画持续时间
[ UIView setAnimationDuration :3.0f];
// 改变 text 的位置大小
_textView . frame = CGRectMake (100, 100, 300, 300);
// 改变 text 的颜色
_textView . backgroundColor = [ UIColor yellowColor ];
// 改变 text 的透明度
_textView . alpha = 0.5;
// 动画进入的效果
[ UIView setAnimationCurve : UIViewAnimationCurveEaseIn ];
// 动画延迟时间
// [UIView setAnimationDelay:2.0f];
// 重复次数
[ UIView setAnimationRepeatCount :1000];
// 动画 恢复效果
[ UIView setAnimationRepeatAutoreverses : YES ];
// 提交动画 让动画去执行
[ UIView commitAnimations ];
// // 点击触发翻页效果 ( 放 touchbegan 里 )
// [UIView setAnimationTransition:(UIViewAnimationTransitionCurlUp) forView:_textView cache:YES];
// 设置代理 ( 并没有协议 )
[ UIView setAnimationDelegate : self ];
// 给动画设置好代理后 , 就会执行动画开始和结束的方法
// UIView setAnimationWillStartSelector:<#(nullable SEL)#>
// UIView setAnimationDidStopSelector:<#(nullable SEL)#>
#pragma mark --- 块动画
- ( void )textViewAction{
// 开始执行动画
// 参数 1 : 动画名字
// 参数 2 : 动画的设置 保留字段
[ UIView beginAnimations : @"oneAnimation" context : nil ];
// 从当前的状态开始执行动画 ( 效果不明显 )
[ UIView setAnimationBeginsFromCurrentState : YES ];
// 动画持续时间
[ UIView setAnimationDuration :3.0f];
// 改变 text 的位置大小
_textView . frame = CGRectMake (100, 100, 300, 300);
// 改变 text 的颜色
_textView . backgroundColor = [ UIColor yellowColor ];
// 改变 text 的透明度
_textView . alpha = 0.5;
// 动画进入的效果
[ UIView setAnimationCurve : UIViewAnimationCurveEaseIn ];
// 动画延迟时间
// [UIView setAnimationDelay:2.0f];
// 重复次数
[ UIView setAnimationRepeatCount :1000];
// 动画 恢复效果
[ UIView setAnimationRepeatAutoreverses : YES ];
// 提交动画 让动画去执行
[ UIView commitAnimations ];
// // 点击触发翻页效果 ( 放 touchbegan 里 )
// [UIView setAnimationTransition:(UIViewAnimationTransitionCurlUp) forView:_textView cache:YES];
// 设置代理 ( 并没有协议 )
[ UIView setAnimationDelegate : self ];
// 给动画设置好代理后 , 就会执行动画开始和结束的方法
// UIView setAnimationWillStartSelector:<#(nullable SEL)#>
// UIView setAnimationDidStopSelector:<#(nullable SEL)#>
}
#pragma mark--- UIViewBlock
动画
- ( void )uiViewBlock{
__weak typeof ( self ) pSelf = self ;
//1) 最简单的 block 动画 , 只需要设置一个时间就可以
[ UIView animateWithDuration :1.0f animations :^{
pSelf. textView . frame = CGRectMake (100, 100, 300, 300);
pSelf. textView . backgroundColor = [ UIColor redColor ];
}];
//2) 两个 block
// 执行动画的 和 动画结束后执行的
[ UIView animateWithDuration :1.0f animations :^{
pSelf. textView . backgroundColor = [ UIColor grayColor ];
} completion :^( BOOL finished) {
if (finished) {
NSLog ( @" 动画执行完了之后 " );
pSelf. textView . backgroundColor = [ UIColor yellowColor ];
}
}];
//3) 有延迟和设置的
[ UIView animateWithDuration :1.0f delay :1.0f options :( UIViewAnimationOptionTransitionCrossDissolve ) animations :^{
pSelf. textView . frame = CGRectMake (200, 200, 50, 50);
} completion :^( BOOL finished) {
NSLog ( @" 动画执行完了之后 " );
}];
- ( void )uiViewBlock{
__weak typeof ( self ) pSelf = self ;
//1) 最简单的 block 动画 , 只需要设置一个时间就可以
[ UIView animateWithDuration :1.0f animations :^{
pSelf. textView . frame = CGRectMake (100, 100, 300, 300);
pSelf. textView . backgroundColor = [ UIColor redColor ];
}];
//2) 两个 block
// 执行动画的 和 动画结束后执行的
[ UIView animateWithDuration :1.0f animations :^{
pSelf. textView . backgroundColor = [ UIColor grayColor ];
} completion :^( BOOL finished) {
if (finished) {
NSLog ( @" 动画执行完了之后 " );
pSelf. textView . backgroundColor = [ UIColor yellowColor ];
}
}];
//3) 有延迟和设置的
[ UIView animateWithDuration :1.0f delay :1.0f options :( UIViewAnimationOptionTransitionCrossDissolve ) animations :^{
pSelf. textView . frame = CGRectMake (200, 200, 50, 50);
} completion :^( BOOL finished) {
NSLog ( @" 动画执行完了之后 " );
}];
//4) 有回弹效果
Spring
//
参数
1 :
持续时间
// 参数 2 : 延迟时间
// 参数 2 : 延迟时间
// 0 ~ 1
阻尼系数
//动画初始变化速率
[
UIView
animateWithDuration
:2.0f
delay
:1.0f
usingSpringWithDamping
:0.1
initialSpringVelocity
:10
options
:(
UIViewAnimationOptionRepeat
)
animations
:^{
pSelf. textView . frame = CGRectMake (200, 200, 50, 50);
} completion :^( BOOL finished) {
NSLog ( @"1111" );
}];
pSelf. textView . frame = CGRectMake (200, 200, 50, 50);
} completion :^( BOOL finished) {
NSLog ( @"1111" );
}];
}
#pragma mark
关键帧动画
- ( void )keyframeAnimation{
__weak typeof ( self ) pSelf = self ;
[ UIView animateKeyframesWithDuration :4 delay :0 options :( UIViewKeyframeAnimationOptionRepeat ) animations :^{
// 参数 1 : 为开始时间
// 参数 2 : 为持续时间
// 真正的时间 startime(relativeDuration) * duration
[ UIView addKeyframeWithRelativeStartTime :0 relativeDuration :0.25 animations :^{
pSelf. textView . backgroundColor = [ UIColor grayColor ];
}];
[ UIView addKeyframeWithRelativeStartTime :0.5 relativeDuration :0.25 animations :^{
pSelf. textView . frame = CGRectMake (200, 200, 100, 100);
}];
} completion :^( BOOL finished) {
}];
- ( void )keyframeAnimation{
__weak typeof ( self ) pSelf = self ;
[ UIView animateKeyframesWithDuration :4 delay :0 options :( UIViewKeyframeAnimationOptionRepeat ) animations :^{
// 参数 1 : 为开始时间
// 参数 2 : 为持续时间
// 真正的时间 startime(relativeDuration) * duration
[ UIView addKeyframeWithRelativeStartTime :0 relativeDuration :0.25 animations :^{
pSelf. textView . backgroundColor = [ UIColor grayColor ];
}];
[ UIView addKeyframeWithRelativeStartTime :0.5 relativeDuration :0.25 animations :^{
pSelf. textView . frame = CGRectMake (200, 200, 100, 100);
}];
} completion :^( BOOL finished) {
}];
}
注: UIView的addKeyframeWithRelativeStartTime方法必须实现在 UIView的animateKeyframesWithDuration的animation参数函数块中
CoreAnimation动画
- CoreAnimation动画位于iOS框架的Media层
- CoreAnimation动画实现需要添加QuartzCore.Framework
- CoreAnimation基本上是Layer Animation
CALayer基本介绍:
- CALayer负责绘制, 提供UIView需要展示的内容, 不能交互
- UIView负责交互,显示CALayer绘制的内容
CALayer(层)是屏幕上的一个矩形区域, 在每一个UIView中都包含一个根CALayer, 在UIView上的所以视觉效果都是在这个Layer上进行的.
CALayer外形特征主要包括:
- 层的大小尺寸
- 背景色
- 内容(可以填充图片或者使用Core Graphics绘制的内容)
- 积习是否使用圆角
- 矩形是否有阴影
CALayer常用属性:
与UIView动画相比, CoreAnimation能够实现更多复杂, 好看, 高效的动画效果:
- 阴影, 圆角, 带颜色的边框
- 3D变换
- 透明遮罩
- 多级非线性动画
- CABasicAnimation基本单一类型的动画
- CAKeyframeAnimation 帧动画, 主要操作属性与keyPath 和 values值组合
- CAAnimationGroup组合动画, 操作属性: animations将CAAnimation类型的动画加入数组, FIFO队列的方式执行
- (
void
)transitonAction{
UIView *view = [[ UIView alloc ] initWithFrame : CGRectMake (100, 100, 100, 100)];
view. backgroundColor = [ UIColor redColor ];
[ self . view addSubview :view];
#pragma mark --- 核心层动画
CATransition *transition = [[ CATransition alloc ] init ];
// 时长
transition. duration = 1.0f;
// 动画的类型
transition. type = @"moveIn" ;
// 动画的方向
transition. subtype = kCATransitionFromTop ;
// 重复次数
transition. repeatCount = 100;
// 一定要加到 layer 上 , 后面的 key 是方便 移除的
[view. layer addAnimation :transition forKey : @"key" ];
}
UIView *view = [[ UIView alloc ] initWithFrame : CGRectMake (100, 100, 100, 100)];
view. backgroundColor = [ UIColor redColor ];
[ self . view addSubview :view];
#pragma mark --- 核心层动画
CATransition *transition = [[ CATransition alloc ] init ];
// 时长
transition. duration = 1.0f;
// 动画的类型
transition. type = @"moveIn" ;
// 动画的方向
transition. subtype = kCATransitionFromTop ;
// 重复次数
transition. repeatCount = 100;
// 一定要加到 layer 上 , 后面的 key 是方便 移除的
[view. layer addAnimation :transition forKey : @"key" ];
}
- (
void
)basicAnimation{
UIView *view = [[ UIView alloc ] initWithFrame : CGRectMake (100, 100, 100, 100)];
view. backgroundColor = [ UIColor redColor ];
[ self . view addSubview :view];
#pragma mark ---- CABasicAnimation
// CABasicAnimation 的 keyPath 必须是 CALayer 中存在的属性且注释里面有 Animatable 这个字段才可以使用 ( 旋转 , 放大 , 之类方法 )
CABasicAnimation *basicAnimation = [ CABasicAnimation animationWithKeyPath : @"transform.rotation" ];
basicAnimation. duration = 4.0f;
// 动画小朵变化的初始值
basicAnimation. fromValue = @( M_PI );
// 动画效果变化的结果值 ( 绝对值 )
basicAnimation. toValue = @( M_PI * 2);
// 即 动画效果变化的结束值 ( 相对值 )
// basicAnimation.byValue = @(M_PI);
// 即 byValue = to - from
// basicAnimation.repeatCount = 100;
[view. layer addAnimation :basicAnimation forKey : @"newKey" ];
UIView *view = [[ UIView alloc ] initWithFrame : CGRectMake (100, 100, 100, 100)];
view. backgroundColor = [ UIColor redColor ];
[ self . view addSubview :view];
#pragma mark ---- CABasicAnimation
// CABasicAnimation 的 keyPath 必须是 CALayer 中存在的属性且注释里面有 Animatable 这个字段才可以使用 ( 旋转 , 放大 , 之类方法 )
CABasicAnimation *basicAnimation = [ CABasicAnimation animationWithKeyPath : @"transform.rotation" ];
basicAnimation. duration = 4.0f;
// 动画小朵变化的初始值
basicAnimation. fromValue = @( M_PI );
// 动画效果变化的结果值 ( 绝对值 )
basicAnimation. toValue = @( M_PI * 2);
// 即 动画效果变化的结束值 ( 相对值 )
// basicAnimation.byValue = @(M_PI);
// 即 byValue = to - from
// basicAnimation.repeatCount = 100;
[view. layer addAnimation :basicAnimation forKey : @"newKey" ];
}
- ( void )keyFrameAnimation{
UIView *view = [[ UIView alloc ] initWithFrame : CGRectMake (100, 100, 100, 100)];
view. backgroundColor = [ UIColor redColor ];
[ self . view addSubview :view];
CAKeyframeAnimation *keyAnimation = [ CAKeyframeAnimation animationWithKeyPath : @"position" ];
keyAnimation. duration = 5.0f;
NSValue *value = [ NSValue valueWithCGPoint : CGPointMake (200, 200)];
NSValue *value2 = [ NSValue valueWithCGPoint : CGPointMake (123, 321)];
NSValue *value3 = [ NSValue valueWithCGPoint : CGPointMake (222, 111)];
NSValue *value4 = [ NSValue valueWithCGPoint : CGPointMake (50, 120)];
keyAnimation. values = @[value, value2, value3, value4];
// [view.layer addAnimation:keyAnimation forKey:@"keyAnimation"];
CAKeyframeAnimation *keyAnimation1 = [ CAKeyframeAnimation animationWithKeyPath : @"backgroudColor" ];
id color = ( id )[ UIColor greenColor ]. CGColor ;
id color2 = ( id )[ UIColor yellowColor ]. CGColor ;
id color3 = ( id )[ UIColor cyanColor ]. CGColor ;
id color4 = ( id )[ UIColor blackColor ]. CGColor ;
keyAnimation1. values = @[color, color2, color3, color4];
CAAnimationGroup *group = [ CAAnimationGroup animation ];
group. animations = @[keyAnimation, keyAnimation1];
group. duration = 5.0f;
group. repeatCount = 10;
// [view.layer addAnimation:keyAnimation1 forKey:@"keyAnimation1"];
[view.layer
addAnimation
:group
forKey
:
@"group"
];
}
- 动画分为两种属性动画和过渡动画
- UIView层的实现分为两种 : begin/commit和block
- Layer层动画分为三种 : CAPropertyAnimation, CATransion, CAAnimationGroup.