一、首尾式动画
如果只是修改控件的属性,使用首尾式动画还是比较方便的,但是如果需要在动画完成后做后续处理,就不是那么方便了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
#import "ViewController.h"
@interface
ViewController
(
)
@property
(
strong
,
nonatomic
)
UIButton
*btn
;
@end
@implementation
ViewController
-
(
void
)
viewDidLoad
{
[
super
viewDidLoad
]
;
//创建一个宽高50、坐标10,10的按钮
self
.
btn
=
[
[
UIButton
alloc
]
initWithFrame
:CGRectMake
(
10
,
20
,
50
,
50
)
]
;
//按钮背景颜色为红色
[
self
.
btn
setBackgroundColor
:
[
UIColor
redColor
]
]
;
//添加单击事件
[
self
.
btn
addTarget
:self
action
:
@selector
(
click
)
forControlEvents
:UIControlEventTouchUpInside
]
;
//将按钮添加到父容器中
[
self
.
view
addSubview
:self
.
btn
]
;
}
//单击事件
-
(
void
)
click
{
CGRect
btnFrame
=
self
.
btn
.
frame
;
btnFrame
.
origin
.
x
+=
50
;
btnFrame
.
origin
.
y
+=
50
;
//beginAnimations表示此后的代码要"参与到"动画中
[
UIView
beginAnimations
:nil
context
:nil
]
;
//设置动画时长
[
UIView
setAnimationDuration
:
1
]
;
//修改按钮的frame
self
.
btn
.
frame
=
btnFrame
;
//commitAnimations,将beginAnimation之后的所有动画提交并生成动画
[
UIView
commitAnimations
]
;
}
-
(
void
)
didReceiveMemoryWarning
{
[
super
didReceiveMemoryWarning
]
;
}
@end
|
二、block代码块动画
在实际的开发中更常用的时block代码块来处理动画操作,块动画相对来说比较灵活,尤为重要的是能够将动画相关的代码编写在一起,便于代码的阅读和理解。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
#import "ViewController.h"
@interface
ViewController
(
)
@property
(
strong
,
nonatomic
)
UIButton
*btn
;
@end
@implementation
ViewController
-
(
void
)
viewDidLoad
{
[
super
viewDidLoad
]
;
//创建一个宽高50、坐标10,10的按钮
self
.
btn
=
[
[
UIButton
alloc
]
initWithFrame
:CGRectMake
(
10
,
20
,
50
,
50
)
]
;
//按钮背景颜色为红色
[
self
.
btn
setBackgroundColor
:
[
UIColor
redColor
]
]
;
//添加单击事件
[
self
.
btn
addTarget
:self
action
:
@selector
(
click
)
forControlEvents
:UIControlEventTouchUpInside
]
;
//将按钮添加到父容器中
[
self
.
view
addSubview
:self
.
btn
]
;
}
-
(
void
)
click
{
CGRect
btnFrame
=
self
.
btn
.
frame
;
btnFrame
.
origin
.
x
+=
50
;
btnFrame
.
origin
.
y
+=
50
;
//代码块内的代码是执行动画的代码
[
UIView
animateWithDuration
:
1
animations
:
^
{
//修改按钮的frame
self
.
btn
.
frame
=
btnFrame
;
}
]
;
}
-
(
void
)
didReceiveMemoryWarning
{
[
super
didReceiveMemoryWarning
]
;
}
@end
|
三、序列帧动画
如果给UIImageView的animationImages赋值一个元素全部为UIImage的数组,并进行相关属性设置就能开启帧动画。所谓帧动画就像老电影院里播放电影的胶片,顺序播放每个胶片让画面看起来就像动画一样,其实就是一大堆图片轮播效果。
为UIImageView对象的animationImages属性赋值一个图片资源数组
1
|
@property
(
nullable
,
nonatomic
,
copy
)
NSArray
<
UIImage
*
>
*animationImages
;
|
设置动画执行时间
1
|
@property
(
nonatomic
)
NSTimeInterval
animationDuration
;
|
设置动画循环次数
1
|
@property
(
nonatomic
)
NSInteger
animationRepeatCount
;
|
动画的开启、停止和判断是否正在执行
1
2
3
|
-
(
void
)
startAnimating
;
-
(
void
)
stopAnimating
;
-
(
BOOL
)
isAnimating
;
|
新建一个Single View Application项目,导入准备好的图片素材,不需要拖拽任何控件。
实现代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
#import "ViewController.h"
@interface
ViewController
(
)
@property
(
strong
,
nonatomic
)
UIImageView
*img
;
//图
@end
@implementation
ViewController
-
(
void
)
viewDidLoad
{
[
super
viewDidLoad
]
;
self
.
img
=
[
[
UIImageView
alloc
]
initWithFrame
:CGRectMake
(
0
,
0
,
375
,
667
)
]
;
//添加图片
self
.
img
.
image
=
[
UIImage
imageWithContentsOfFile
:
[
[
NSBundle
mainBundle
]
pathForResource
:
@"tyler_001.jpg"
ofType
:nil
]
]
;
//显示图片
[
self
.
view
addSubview
:self
.
img
]
;
//显示按钮
[
self
addEatBtnView
]
;
}
-
(
void
)
didReceiveMemoryWarning
{
[
super
didReceiveMemoryWarning
]
;
// Dispose of any resources that can be recreated.
}
//吃鸟的按钮
-
(
void
)
addEatBtnView
{
UIButton
*eatBtn
=
[
[
UIButton
alloc
]
initWithFrame
:CGRectMake
(
30
,
550
,
45
,
45
)
]
;
//设置按钮背景图
[
eatBtn
setBackgroundImage
:
[
UIImage
imageNamed
:
@"eat"
]
forState
:UIControlStateNormal
]
;
//添加单击事件
[
eatBtn
addTarget
:self
action
:
@selector
(
tyler
)
forControlEvents
:UIControlEventTouchUpInside
]
;
//显示按钮
[
self
.
view
addSubview
:eatBtn
]
;
}
//单击事件
-
(
void
)
tyler
{
[
self
startAnimationWithCount
:
30
andName
:
@"tyler"
]
;
}
//播放帧动画
-
(
void
)
startAnimationWithCount
:
(
int
)
count
andName
:
(
NSString
*
)
name
{
//如果动画正在播放就不会继续播放下一个动画
if
(
self
.
img
.
isAnimating
)
{
return
;
}
//循环创建UIImage并添加到数组中
NSMutableArray
*arrayM
=
[
[
NSMutableArray
alloc
]
init
]
;
for
(
int
i
=
0
;
i
<
count
-
1
;
i
++
)
{
//拼接图片名称
NSString
*imgName
=
[
NSString
stringWithFormat
:
@"%@_%03d.jpg"
,
name
,
i
+
1
]
;
//根据图片名称查找app安装后的图片绝对路径
NSString
*path
=
[
[
NSBundle
mainBundle
]
pathForResource
:imgName
ofType
:nil
]
;
//根据图片路径加载图片数据
UIImage
*imgTemp
=
[
UIImage
imageWithContentsOfFile
:path
]
;
//将图片名存储到数组
[
arrayM
addObject
:imgTemp
]
;
}
//为animationImages属性赋值一个数组
self
.
img
.
animationImages
=
arrayM
;
//设置帧动画播放时间
self
.
img
.
animationDuration
=
arrayM
.
count
*
0.1
;
//设置帧动画播放次数
self
.
img
.
animationRepeatCount
=
1
;
//开启动画
[
self
.
img
startAnimating
]
;
//释放内存
[
self
.
img
performSelector
:
@selector
(
setAnimationImages
:
)
withObject
:nil
afterDelay
:arrayM
.
count
*
0.1
]
;
}
@end
|
最终效果图: