方块动画;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
更多精彩内容请关注“IT实战联盟”哦~~~
![IT实战联盟.jpg](https://img.haomeiwen.com/i326255/f67b0f0dd5fe5874.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/500)
网友评论