新版本的UI需求中有一条是图1中红框中的倾斜效果。
要实现这个效果,开始有两种思路,第一种是在UILabel中把文字倾斜,然后把左边、中间、右边的倾斜部分单独切图,拼出这个效果。第二种是先实现不倾斜的版本,然后对整体进行一个倾斜的变换。显然第二种办法通用性更强,所以选择了第二种。
第一步实现不倾斜的版本很简单,左右各用一个UILabel,分别使用不同的字体颜色、背景颜色和边框颜色。
第二步对两个label进行剪切变换,让其倾斜相同的角度。
直接上代码
let transform = CGAffineTransform(a: 1, b: 0, c: -0.104911, d: 1, tx: 0, ty: 0)
label.transform = transform // 对label设置变换
label.layer.shouldRasterize = true //去锯齿
代码中CGAffineTransform是做仿射变换的矩阵,本文用到的剪切变换是仿射变换的一种。参数b决定了垂直方向的倾斜度,参数c决定了水平方向的倾斜度。计算b和c可以用这个网址,将倾斜的角度输入,然后将计算出的正弦双曲函数结果作为这里的参数c,余弦双曲函数结果作为参数b。在本文的需求中,label在水平方向倾斜6度,在垂直方向没有倾斜(0度),只要将b和c分别算出来即可。图2为计算参数c的取值。如果角度正负号搞不清楚,可以多试两次。剩下的参数a,d,tx,ty在仿射变换中都有对应的用途,在本例的剪切变换中保持为固定值即可。