//设置类型有两种方式,一种是字符串,一种是系统宏 // anim.type = @"cube"; // anim.type = kCATransitionPush;
//subtype: 设置方向
// anim.subtype = kCATransitionFromRight;
//动画持续时间 // anim.duration = 1; // 设置动画进度.0->1 // anim.startProgress = 0.5; 从动画进行一半开始 // anim.endProgress = 0.5; 动画进行一半结束 CATransition *anim = [CATransition animation]; anim.type = @"cube"; anim.subtype = kCATransitionFromRight; anim.duration = 1; [self.redView.layer addAnimation:anim forKey:nil];
属性:
@property(copy) NSString *type; @property(nullable, copy) NSString *subtype; @property float startProgress; @property float endProgress; @property(nullable, strong) id filter; type类型:/* Common transition types. */ kCATransitionFade kCATransitionMoveIn kCATransitionPush kCATransitionReveal
fade
push
moveIn
reveal
oglFlip
cube
suckEffect
rippleEffect
pageCurl
pageUnCurl
cameraIrisHollowOpen
cameraIrisHollowClose
subtype类型:
kCATransitionFromRight
kCATransitionFromLeft
kCATransitionFromTop
kCATransitionFromBottom
CATransition
类继承于CAAnimation
类,提供的是过滤的效果,如push
、fade
、reveal
等。
type
属性是用于指定效果类型,当前官方提供的效果有fade
, moveIn
, push
和reveal
. 默认为fade
。对于其它类型,如cube
立体效果这种官方没有公开,也不清楚是否是使用私有。
subtype
属性是可选的,主要用于指定动画的方向。比如动作类动画效果中,有从左边进入、从右边进入等效果。
这两个属性可以设置动画动作的进度,默认为0->1。
filter
属性默认为nil
,一旦设置了此属性,type
和subtype
就会被忽略。 这个属性意思就是滤镜的意思吧,它需要实现inputImage
、inputTargetImage
、inputTime
、outputImage
,当然还有一个可选的inputExtent
,不要求实现。
更多基础知识,请参考:CAAnimation精讲
实战练习做动画
先看看我们做效果图:
常用的transition
动画几乎都有了,而且笔者在学习的同时,也这将些动画封装成了一个类方法,只需要一行代码就可以实现动画效果了哦!
头文件声明
这里只公共了一个方法,并将常用的动画使用一个枚举类型来指定,不用再记着那些单词了。
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
|
//
// HYBTransitionAnimation.h
// CATransitionOfObjCDemo
//
// Created by huangyibiao on 15/12/14.
// Copyright © 2015年 huangyibiao. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
typedef NS_ENUM(NSUInteger, HYBTransitionType) {
kHYBTransitionFade = 1, // 淡入淡出
kHYBTransitionPush, // 推进效果
kHYBTransitionReveal, // 揭开效果
kHYBTransitionMoveIn, // 慢慢进入并覆盖效果
kHYBTransitionCube, // 立体翻转效果
kHYBTransitionSuckEffect, // 像被吸入瓶子的效果
kHYBTransitionRippleEffect, // 波纹效果
kHYBTransitionPageCurl, // 翻页效果
kHYBTransitionPageUnCurl, // 反翻页效果
kHYBTransitionCameraOpen, // 开镜头效果
kHYBTransitionCameraClose, // 关镜头效果
kHYBTransitionCurlDown, // 下翻页效果
kHYBTransitionCurlUp, // 上翻页效果
kHYBTransitionFlipFromLeft, // 左翻转效果
kHYBTransitionFlipFromRight,// 右翻转效果
kHYBTransitionOglFlip // 翻转
};
typedef NS_ENUM(NSUInteger, HYBTransitionSubtype) {
kHYBTransitionSubtypeFromLeft = 1, // 从左边进入
kHYBTransitionSubtypeFromRight, // 从右边进入
kHYBTransitionSubtypeFromTop, // 从顶部进入
kHYBTransitionSubtypeFromBottom // 从底部进入
};
@interface HYBTransitionAnimation : NSObject
+ (void)transitionForView:(UIView *)aView
type:(HYBTransitionType)type
subtype:(HYBTransitionSubtype)subtype
duration:(NSTimeInterval)duration;
@end
|
实现文件
其实实现的代码也很简单,只是对枚举类型判断一下,然后添加动画:
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
//
// HYBTransitionAnimation.m
// CATransitionOfObjCDemo
//
// Created by huangyibiao on 15/12/14.
// Copyright © 2015年 huangyibiao. All rights reserved.
//
#import "HYBTransitionAnimation.h"
@implementation HYBTransitionAnimation
+ (void)transitionForView:(UIView *)aView
type:(HYBTransitionType)type
subtype:(HYBTransitionSubtype)subtype
duration:(NSTimeInterval)duration {
NSString *animationType = nil;
NSString *animationSubtype = nil;
switch (subtype) {
case kHYBTransitionSubtypeFromLeft:
animationSubtype = kCATransitionFromLeft;
break;
case kHYBTransitionSubtypeFromRight:
animationSubtype = kCATransitionFromRight;
break;
case kHYBTransitionSubtypeFromTop:
animationSubtype = kCATransitionFromTop;
break;
case kHYBTransitionSubtypeFromBottom:
animationSubtype = kCATransitionFromBottom;
break;
default:
break;
}
switch (type) {
case kHYBTransitionFade: {
animationType = kCATransitionFade;
break;
}
case kHYBTransitionPush: {
animationType = kCATransitionPush;
break;
}
case kHYBTransitionReveal: {
animationType = kCATransitionReveal;
break;
}
case kHYBTransitionMoveIn: {
animationType = kCATransitionMoveIn;
break;
}
case kHYBTransitionCube: {
animationType = @"cube";
break;
}
case kHYBTransitionSuckEffect: {
animationType = @"suckEffect";
break;
}
case kHYBTransitionRippleEffect: {
animationType = @"rippleEffect";
break;
}
case kHYBTransitionPageCurl: {
animationType = @"pageCurl";
break;
}
case kHYBTransitionPageUnCurl: {
animationType = @"pageUnCurl";
break;
}
case kHYBTransitionCameraOpen: {
animationType = @"cameraIrisHollowOpen";
break;
}
case kHYBTransitionCameraClose: {
animationType = @"cameraIrisHollowClose";
break;
}
case kHYBTransitionCurlDown: {
[self animationForView:aView type:UIViewAnimationTransitionCurlDown duration:duration];
break;
}
case kHYBTransitionCurlUp: {
[self animationForView:aView type:UIViewAnimationTransitionCurlUp duration:duration];
break;
}
case kHYBTransitionFlipFromLeft: {
[self animationForView:aView type:UIViewAnimationTransitionFlipFromLeft duration:duration];
break;
}
case kHYBTransitionFlipFromRight: {
[self animationForView:aView type:UIViewAnimationTransitionFlipFromRight duration:duration];
break;
}
case kHYBTransitionOglFlip:
animationType = @"oglFlip";
break;
default: {
break;
}
}
if (animationType != nil) {
CATransition *animation = [CATransition animation];
animation.duration = duration;
animation.type = animationType;
if (animationSubtype != nil) {
animation.subtype = animationSubtype;
}
animation.timingFunction = UIViewAnimationOptionCurveEaseInOut;
[aView.layer addAnimation:animation forKey:@"animation"];
}
}
+ (void)animationForView:(UIView *)aView
type:(UIViewAnimationTransition)type
duration:(NSTimeInterval)duration {
[UIView animateWithDuration:duration animations:^{
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:type forView:aView cache:YES];
}];
}
@end
|
解析
我们的核心添加动画的代码是:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
CATransition *animation = [CATransition animation];
animation.duration = duration;
animation.type = animationType;
if (animationSubtype != nil) {
animation.subtype = animationSubtype;
}
animation.timingFunction = UIViewAnimationOptionCurveEaseInOut;
[aView.layer addAnimation:animation forKey:@"animation"];
|
系统提供给我们一些动画是在UIView
上提供的方法,我们可以看看这个枚举:
1
2
3
4
5
6
7
8
9
|
typedef NS_ENUM(NSInteger, UIViewAnimationTransition) {
UIViewAnimationTransitionNone,
UIViewAnimationTransitionFlipFromLeft,
UIViewAnimationTransitionFlipFromRight,
UIViewAnimationTransitionCurlUp,
UIViewAnimationTransitionCurlDown,
};
|
我们添加动画只需要调用UIView
添加动画的方法就可以实现了:
1
2
3
4
5
6
|
[UIView animateWithDuration:duration animations:^{
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:type forView:aView cache:YES];
}];
|
测试效果
我们在ViewController
这里尝试一下效果,这里只是使用定时器每一秒就自动切换一种效果:
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
84
85
86
87
88
89
90
91
|
//
// ViewController.m
// CATransitionOfObjCDemo
//
// Created by huangyibiao on 15/12/14.
// Copyright © 2015年 huangyibiao. All rights reserved.
//
#import "ViewController.h"
#import "HYBTransitionAnimation.h"
@interface ViewController ()
@property (nonatomic, assign) int subtype;
@property (nonatomic, strong) NSArray *array;
@property (nonatomic, strong) UIImage *img1;
@property (nonatomic, strong) UIImage *img2;
@property (nonatomic, assign) BOOL isImg1;
@property (nonatomic, assign) NSUInteger index;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.array = @[@(kHYBTransitionFade),
@(kHYBTransitionPush),
@(kHYBTransitionReveal),
@(kHYBTransitionMoveIn),
@(kHYBTransitionCube),
@(kHYBTransitionSuckEffect),
@(kHYBTransitionRippleEffect),
@(kHYBTransitionPageCurl),
@(kHYBTransitionPageUnCurl),
@(kHYBTransitionCameraOpen),
@(kHYBTransitionCameraClose),
@(kHYBTransitionCurlDown),
@(kHYBTransitionCurlUp),
@(kHYBTransitionFlipFromLeft),
@(kHYBTransitionFlipFromRight),
@(kHYBTransitionOglFlip)];
self.img1 = [UIImage imageNamed:@"1.png"];
self.img2 = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"3" ofType:@"jpg"]];
self.view.backgroundColor = [UIColor colorWithPatternImage:self.img1];
self.isImg1 = YES;
[NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:@selector(updateAnimation)
userInfo:nil
repeats:YES];
}
- (void)updateAnimation {
if (self.index >= self.array.count) {
self.index = 0;
}
HYBTransitionType type = [[self.array objectAtIndex:self.index++] intValue];
static int s_subtypeValue = 0;
HYBTransitionSubtype subtype = kHYBTransitionSubtypeFromTop;
s_subtypeValue++;
if (s_subtypeValue >= 4) {
s_subtypeValue = 1;
}
subtype = (HYBTransitionSubtype)s_subtypeValue;
[HYBTransitionAnimation transitionForView:self.view
type:type
subtype:subtype
duration:1.0];
if (self.isImg1) {
self.view.backgroundColor = [UIColor colorWithPatternImage:self.img1];
} else {
self.view.backgroundColor = [UIColor colorWithPatternImage:self.img2];
}
self.isImg1 = !self.isImg1;
}
@end
|