http://sxiaojian.com/2015/11/30/iOS-curve-gradient/
圆形渐变
最近产品提了一个需求,要求进度条的进度可以大于1。效果如下
效果图上卡,实际上并不卡。
在开始做之前,看了github上所有的progress相关的代码,发现并没有人实现过这样的效果。苹果apple watch应用实现了,但是不知道苹果是怎么实现的。
这个效果的难度就在于 曲线渐变 和 进度能大于1。
cocoa touch提供的api都是直线渐变。而进度可以大于1要求曲线的首和尾颜色不能想近,应该相差最大。
这篇文章实现了一个曲线渐变,但是这个无法实现进度条大于一。
最终要想实现曲线渐变只能自己实现了。
颜色的生成
一共需要两个颜色,起始颜色和结束颜色。中间颜色的R、G、B值由progress线性生成。
CGFloat ratio =(float)i /(float)sectors;CGFloat R = beginR +(endR- beginR)* ratio;CGFloat G = beginG +(endG- beginG)* ratio;CGFloat B = beginB +(endB- beginB)* ratio;
渐变的生成
由于apple提供的api都是直线的,我就采取了微分的思想,将一个圆分为无数份,然后每一份绘制一点颜色。最终就形成了曲线渐变。
最终的实现
直接看代码吧。demo在此
rounded矩形渐变
这个动画的实现就更有难度了。
动画由两个CAReplicatorLayer组成,一个完成前半部分,一个完成后半部份,两个layer的属性完全一致,仅仅是另外一个layer旋转了180度。最终效果是这样。
一个CAReplicatorLayer的动画是这样的
由于stroke end的取值是0-1,所以无法平滑的让stroke一直保持一样的长度。为了实现效果,我采取的方法是创建一个一样的CAReplicatorLayer并旋转180度。
于是效果变成了这样
然后在这两个layer的superLayer添加mask,最终完成了要求的动画效果。
最难的是CAReplicatorLayer的创建,我创建了40个instance。
replicator.instanceCount = 40;replicator.instanceDelay = 0.01;replicator.instanceColor = [UIColor colorWithRed:1 green: 0.373 blue:0 alpha:0.99].CGColor;replicator.instanceRedOffset = 0.005;replicator.instanceGreenOffset = 0.005;replicator.instanceBlueOffset = 0.005;replicator.instanceAlphaOffset = -0.03;replicator.instanceTransform = CATransform3DIdentity;
里面的参数都经过大量的试错与微调才调出这个效果。