iOS Animation (二)

2015-11-28  本文已影响0人  simuty

方块动画;Cube Animation

怎么简单实现类似于3D动画的样式?

我们可以声明一个新的替代label

funccubeTransition(labellabel:UILabel, text:String, direction:AnimationDirection){

letauxLabel=UILabel(frame: label.frame) auxLabel.text=textauxLabel.font= label.fontauxLabel.textAlignment= label.textAlignmentauxLabel.textColor= label.textColorauxLabel.backgroundColor=UIColor.clearColor()

}

1.label:想要让label实现类似3D动画的label

2.text:显示在Label上的文字

3.direction:显示new label的样式,从上还是从下;

注意事项:

你会发现,新的labelcopy了除了background color以外的所有旧的label属性,因为UIKit有个bug,就是如果你拷贝background color,它会显示不透明的黑色。

你不想在同一位置出现了两个Label,相反,想要让辅助的label不在现有的View上,并且使它最小化。

1、首先要计算辅助label的垂直偏移量;

2、CGFffineTransformMakeTranslation这个转换动画可以移动UIView的位置,这里需要注意它是以初始位置为基础进行移动的,

然后添加动画,oldLabel与auxiliaryLab直接的动画

//方块动画

func cubeTransition(label label: UILabel, text: String, direction:AnimationDirection) {

///创建一个替代label

let auxiliaryLab = UILabel(frame: label.frame)

auxiliaryLab.text = text

auxiliaryLab.font = label.font

auxiliaryLab.textAlignment = label.textAlignment

auxiliaryLab.textColor = label.textColor

//颜色不可以直接复制,UIKit有个Bug

auxiliaryLab.backgroundColor = UIColor.clearColor()

//替代Label的Y偏移量

let auxiliaryLabOffset = CGFloat(direction.rawValue) *

label.frame.size.height / 2

//替代Label的旋转,

//CGAffineTransformMakeScale为按宽高比例,在此为高度的十分之一

//CGFffineTransformMakeTranslation这个转换动画可以移动UIView的位置,这里需要注意它是以初始位置为基础进行移动的

//先将替代

//不同样式可以改变X,有转场的方式从下往上添加,在此可以改变样式

auxiliaryLab.transform = CGAffineTransformConcat(

CGAffineTransformMakeScale(0.5, 0.1),

CGAffineTransformMakeTranslation(0.0, auxiliaryLabOffset))

label.superview!.addSubview(auxiliaryLab)

UIView.animateWithDuration(0.5, delay: 0.0, options: .CurveEaseOut,animations: {

//恢复替代视图的默认状态(每次变换前都要置位,不然你变换用的坐标系统不是屏幕坐标系统(即绝对坐标系统),而是上一次变换后的坐标系统。)

auxiliaryLab.transform = CGAffineTransformIdentity

//将原来的label向上旋转消失(按比例加上位置偏移)

label.transform = CGAffineTransformConcat(

CGAffineTransformMakeScale(1.0,0.1),

CGAffineTransformMakeTranslation(0.0, -auxiliaryLabOffset))

}, completion: {_ in

//恢复默认状态,然后将替代Label的值在此复制给原本的Lable

label.transform =CGAffineTransformIdentity

label.text = auxiliaryLab.text

//remove auxiliaryLable

auxiliaryLab.removeFromSuperview()

})

}

其中关于CGAffineTrans相关的:

矩阵乘法:A B相乘要A的列数等于B的行数才有定义,结果是一个 A行B列的矩阵C,C的每个元素值为A对应的行与B对应的列的元素乘积的和;

原理

CGAffineTransform

CGAffineTransform 的结构如下

struct CGAffineTransform {

CGFloat a;

CGFloat b;

CGFloat c;

CGFloat d;

CGFloat tx;

CGFloat ty;

};

typedef struct CGAffineTransform CGAffineTransform;

它其实表示的是一个矩阵

因为最后一列总是是(0,0,1),所以有用的信息就是前面两列

对一个view进行仿射变化就相当于对view上的每个点做一个乘法

结果就是

基本上就是如果不看c和b的话

a表示x水平方向的缩放,tx表示x水平方向的偏移

d表示y垂直方向的缩放,ty表示y垂直方向的偏移

如果b和c不为零的话,那么视图肯定发生了旋转

常量

CGAffineTransformIdentity

const CGAffineTransformCGAffineTransformIdentity;

这个就是没有变化的最初的样子

创建一个仿射矩阵

CGAffineTransformMake 直接赋值来创建

CGAffineTransformMakeRotation 设置角度来生成矩阵

CGAffineTransformMakeScale  设置缩放,及改变a、d的值

CGAffineTransformMakeTranslation  设置偏移

改变已经存在的放射矩阵

CGAffineTransformTranslate  原始的基础上加上偏移

CGAffineTransformScale加上缩放

CGAffineTransformRotate加上旋转

CGAffineTransformInvert 反向的仿射矩阵比如(x,y)通过矩阵t得到了(x',y')那么通过这个函数生成的t'作用与(x',y')就能得到原始的(x,y)

CGAffineTransformConcat 通过两个已经存在的放射矩阵生成一个新的矩阵t' = t1 * t2

应用仿射矩阵

CGPointApplyAffineTransform 得到新的点

CGSizeApplyAffineTransform  得到新的size

CGRectApplyAffineTransform  得到新的rect

评测矩阵

CGAffineTransformIsIdentity  是否是CGAffineTransformIsIdentity

CGAffineTransformEqualToTransform 看两个矩阵是否相等

应用

放射矩阵一个常用的情形就是根据用户的手势来相应的改变视图的变换

UIPanGestureRecognizer  对应位移

UIPinchGestureRecognizer  对应缩放

UIRotationGestureRecognizer 对应旋转

通常如果需要看到实时的手指移动视图就相应的变换的技巧就是,每次接收到对应的gesture时间就相应的改变view的transform,然后吧这个gesture对应的translation、scale、rotation置为初始值。

参考:iOS Animations by Tutorials

CGAffineTransform 放射变换

更多精彩内容请关注“IT实战联盟”哦~~~

![IT实战联盟.jpg](https://img.haomeiwen.com/i326255/f67b0f0dd5fe5874.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/500)

上一篇 下一篇

猜你喜欢

热点阅读