Mars首页View视图切换动画效果

项目名称:WWViewSwitcher

项目地址:https://github.com/WilliamZhangWH/WWViewSwitcher

效果展示

image

实现代码

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
/* 获得主页显示位置 */
NSInteger positionOfOutsideView = [self.view.subviews indexOfObject:self.outsideView];
/* 记录原始页面位置 */
CATransform3D outsideOriginTransform = self.outsideView.layer.transform;
CATransform3D insideOriginTransform = self.insideView.layer.transform;

CALayer *outsideLayer = self.outsideView.layer;
__block CATransform3D outsideRotationAndPerspectiveTransform = CATransform3DIdentity;

/* 获得主页推后位置 */
outsideRotationAndPerspectiveTransform.m43 = -500;
CATransform3D changedOutsideRotationTransform = outsideRotationAndPerspectiveTransform;

CALayer *insideLayer = self.insideView.layer;
__block CATransform3D insideRotationAndPerspectiveTransform = CATransform3DIdentity;

/* 获得附页推后位置 */
insideRotationAndPerspectiveTransform.m43 = -500;
CATransform3D changeInsideRotationTransform = insideRotationAndPerspectiveTransform;

if (0 == positionOfOutsideView) {/* 主页在后 */
outsideLayer.transform = changedOutsideRotationTransform;
}else{ /* 主页在前 */
insideLayer.transform = changeInsideRotationTransform;
}

/* 展开动画 */
[UIView animateWithDuration:DURATION animations:^{
/* 主页动画变换 */
outsideRotationAndPerspectiveTransform.m34 = 1.0 / -1000;
outsideRotationAndPerspectiveTransform.m41 = WIDTH/3;
outsideRotationAndPerspectiveTransform.m11 = 0.6;
outsideRotationAndPerspectiveTransform.m22 = 0.6;
outsideRotationAndPerspectiveTransform = CATransform3DRotate(outsideRotationAndPerspectiveTransform, M_PI / 3, 0.0f, -1.0f, 0.0f);
outsideLayer.transform = outsideRotationAndPerspectiveTransform;

/* 附页动画变换 */
insideRotationAndPerspectiveTransform.m34 = 1.0 / -1000;
insideRotationAndPerspectiveTransform.m41 = -WIDTH/3;
insideRotationAndPerspectiveTransform.m11 = 0.6;
insideRotationAndPerspectiveTransform.m22 = 0.6;
insideRotationAndPerspectiveTransform = CATransform3DRotate(insideRotationAndPerspectiveTransform, -M_PI / 3, 0.0f, -1.0f, 0.0f);
insideLayer.transform = insideRotationAndPerspectiveTransform;

} completion:^(BOOL finished) {
if (finished) {
/* 收缩动画 */
[UIView animateWithDuration:DURATION animations:^{

if (0 == positionOfOutsideView) { /* 主页在后 */
insideLayer.transform = changeInsideRotationTransform;
outsideLayer.transform = outsideOriginTransform;
}else{ /* 主页在前 */
insideLayer.transform = insideOriginTransform;
outsideLayer.transform = changedOutsideRotationTransform;
}

} completion:^(BOOL finished) {
/* 回复原始状态 */
insideLayer.transform = insideOriginTransform;
outsideLayer.transform = outsideOriginTransform;

/* 交换view的前后位置 */
if (0 == positionOfOutsideView) { /* 主页在后 */
[self.view sendSubviewToBack:self.insideView];
}else{ /* 主页在前 */
[self.view sendSubviewToBack:self.outsideView];
}
}];
}
}];

实现原理

很明显能看出是两个view在交叉切换,交叉的的过程中伴随着缩放、旋转和移动,这个操作的改变基本上是通过CATransform3D中的矩阵值来改变的。

下面是矩阵m11-m44的含义

1
2
3
4
5
6
7
struct CATransform3D
{
CGFloat m11(x缩放), m12(y切变), m13(), m14();
CGFloat m21(x切变), m22(y缩放), m23(), m24();
CGFloat m31(), m32(), m33(), m34(透视效果,要操作的这个对象要有旋转的角度,否则没有效果。);
CGFloat m41(x平移), m42(y平移), m43(z平移), m44();
};

建议可以修改我源码中的矩阵值来理解具体的含义

如果有不明白的地方可以给我留言。欢迎交流!