border渐变 ios_【原】Github系列之三:开源iOS下 渐变颜色的进度条WGradientProgress...

概述

今天我们来实现一个iOS平台上的进度条(progress bar or progress view)。这种进度条比APPLE自带的更加漂亮,更加有“B格”。它拥有渐变的颜色,而且这种颜色是动态移动的,这里称之为WGradientProgress。

先来看看我们的目标长什么样子:

WGradientProgress的使用方法很简单,主要有展示接口以及隐藏接口,目前显示的位置有两种选择:

WProgressPosDown        //progress is on the down border of parent view,显示在parent view的底部(主流做法,默认)

WProgressPosUp       //progress is on the up border of parent view,也就是显示在parent view的顶部

主要的接口有以下几个:

+ (WGradientProgress *)sharedInstance;

/**

* the main interface to show WGradientProgress obj, position is WProgressPosDown by default.

*

* @param parentView which view to be attach

*/

- (void)showOnParent:(UIView *)parentView;

/**

* the main interface to show WGradientProgress obj

*

* @param parentView which view to be attach

* @param pos up or down

*/

- (void)showOnParent:(UIView *)parentView position:(WProgressPos)pos;

/**

* the main interface to hide WGradientProgress obj

*/

- (void)hide;

分析

这里我们看一下,实现出这样的效果需要解决哪些技术难点:

如何实现一个静态的具有渐变颜色的色带

如何实现色带颜色循环移动

如何关联进度值与色带的宽度

(1)如何实现一个静态的具有渐变颜色的色带

这里需要使用CALayer的子类CAGradientLayer。CAGradientLayer用于实现颜色渐变,关于CAGradietnLayer的介绍请看这里。我们使用到的属性有startPoint、endPoint、colors。

我们可以这样子做出一个静态的渐变色带,你也可以修改colors数组来实现不同颜色的色带:

if (self.gradLayer == nil) {

self.gradLayer = [CAGradientLayer layer];

self.gradLayer.frame = self.bounds;//尺寸要与view的layer一致

}

self.gradLayer.startPoint = CGPointMake(0, 0.5);

self.gradLayer.endPoint = CGPointMake(1, 0.5);

//create colors, important section

NSMutableArray *colors = [NSMutableArray array];

for (NSInteger deg = 0; deg <= 360; deg += 5) {

UIColor *color;

color = [UIColor colorWithHue:1.0 * deg / 360.0

saturation:1.0

brightness:1.0

alpha:1.0];

[colors addObject:(id)[color CGColor]];

}

[self.gradLayer setColors:[NSArray arrayWithArray:colors]];

(2)如何实现色带颜色循环移动

色带颜色循环向前移动,本质上是渐变图层gradientLayer的colors数组循环变化。如果理解了这点,那就很容易往下做了。我的做法是使用定时器NSTimer,让定时器的执行方法去循环地改变color数组。另外,既然要做到循环,那么应该循环地取colors数组的最后一个颜色值插到数组开始处。定时器的执行代码如下:

/**

* here I use timer to circularly move colors

*/

- (void)setupTimer

{

CGFloat interval = 0.03;

if (self.timer == nil) {

self.timer = [NSTimer timerWithTimeInterval:interval target:self

selector:@selector(timerFunc)

userInfo:nil repeats:YES];

}

[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSDefaultRunLoopMode];

}

/**

* rearrange color array

*/

- (void)timerFunc

{

CAGradientLayer *gradLayer = self.gradLayer;

NSMutableArray *copyArray = [NSMutableArray arrayWithArray:[gradLayer colors]];

UIColor *lastColor = [copyArray lastObject];

[copyArray removeLastObject];

if (lastColor) {

[copyArray insertObject:lastColor atIndex:0];

}

[self.gradLayer setColors:copyArray];

}

*强势插入:

NSTimer的启动、暂停、永远停止这三个操作要分清,尤其是暂停与停止:

启动:

- (void)startTimer

{

//start timer

[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSDefaultRunLoopMode];

[self.timer setFireDate:[NSDate date]];

}

暂停:

/**

* here we just pause timer, rather than stopping forever.

* NOTE: [timer invalidate] is not fit here.

*/

- (void)pauseTimer

{

[self.timer setFireDate:[NSDate distantFuture]];

}

停止(无法再启动):

[self.timer invalidate]

(3)如何关联进度值与色带的宽度

这个问题看起来很简单,但实际上隐藏着一个很好用的技术:mask。mask也称为蒙版,当我们给一个layer设置了mask layer后,layer就只显示出mask layer所覆盖到的区域,其他区域不显示。用伪代码可以描述为:

CALayer *layer = new

layer.mask = _maskLayer;

layer.visualSection = _maskLayer.bounds;

因此,我们可以将在一开始时就上文的渐变图层gradientLayer大小设置为与view同尺寸,然后通过mask layer设置可见区域。这样,进度条进度值设置问题就转化为mask layer的宽度问题了。

首先,我们添加一个mask layer到gradient layer上:

self.mask = [CALayer layer];

[self.mask setFrame:CGRectMake(self.gradLayer.frame.origin.x, self.gradLayer.frame.origin.y,

self.progress * self.width, self.height)];

self.mask.borderColor = [[UIColor blueColor] CGColor];

self.mask.borderWidth = 2;

[self.gradLayer setMask:self.mask];

[self.layer addSublayer:self.gradLayer];

然后相应进度值的改变如下:

- (void)setProgress:(CGFloat)progress

{

if (progress < 0) {

progress = 0;

}

if (progress > 1) {

progress = 1;

}

_progress = progress;

CGFloat maskWidth = progress * self.width;

self.mask.frame = CGRectMake(0, 0, maskWidth, self.height);

}

以上就是WGradientProgress的主要技术要点,更具体的细节以及使用方法请下载我github上的代码查看,下载时别忘记随手点个Star,给我更多支持与鼓励!

源代码下载:点我。https://github.com/weng1250/WGradientProgressDemo.git

原创文章,转载请注明 编程小翁@博客园,邮件zilin_weng@163.com,欢迎各位与我在C/C++/Objective-C/机器视觉等领域展开交流!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值