【原】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/机器视觉等领域展开交流!
【原】Github系列之三:开源iOS下 渐变颜色的进度条WGradientProgress的更多相关文章
- 渐变颜色的进度条WGradientProgress-备用
今天我们来实现一个iOS平台上的进度条(progress bar or progress view).这种进度条比APPLE自带的更加漂亮,更加有“B格”.它拥有渐变的颜色,而且这种颜色是动态移动的, ...
- .Neter玩转Linux系列之三:Linux下的分区讲解
基础篇 .Neter玩转Linux系列之一:初识Linux .Neter玩转Linux系列之二:Linux下的文件目录及文件目录的权限 .Neter玩转Linux系列之三:Linux下的分区讲解 .N ...
- 纯css使用线性渐变实现滚动进度条(来自于微信前端早读课)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 【iOS实现一个颜色渐变的弧形进度条】
在Github上看到一些进度条的功能,都是通过Core Graph来实现.无所谓正确与否,但是开发效率明显就差很多了,而且运行效率还是值得考究的.其实使用苹果提供的Core Animation能够非常 ...
- iOS实现渐变颜色
下面是我的两种实现: 1.直接图片展示,注意图片的变形问题; 2.用CAGradientLayer渐变颜色实现; 代码如下: // // ViewController.m // ImageStrenc ...
- windows下flv视频网站进度条随意拖放[转]
网站中视频都转换成flv格式,奈何flv格式无法拖拽,此问题纠结了好久,最终得以解决.现将解决思路记录下来,大多数源于网上找到的. 视频拖拽满足要求 1.播放器要支持 2.flv视频要有关键帧和met ...
- iOS 开发技巧-制作环形进度条
有几篇博客写到了怎么实现环形进度条,大多是使用Core Graph来实现,实现比较麻烦且效率略低,只是一个小小的进度条而已,我们当然是用最简单而且效率高的方式来实现. 先看一下这篇博客,博客地址:ht ...
- iOS一分钟学会环形进度条
有几篇博客写到了怎么实现环形进度条,大多是使用Core Graph来实现,实现比较麻烦且效率略低,只是一个小小的进度条而已,我们当然是用最简单而且效率高的方式来实现.先看一下这篇博客,博客地址:htt ...
- MediaPlayer音乐播放器、上一首、下一首、播放、停止、自动下一首、进度条
本文介绍MediaPlayer的使用.MediaPlayer可以播放音频和视频,另外也可以通过VideoView来播放视频,虽然VideoView比MediaPlayer简单易用,但定制性不如用Med ...
随机推荐
- RequireJs调研
背景 Problem(问题) Web sites are turning into Web apps(网站正转变为网络应用程序) Code complexity grows as the site g ...
- 我的Objective-C系列文章
做iOS开发有一段时间了,也有自己上线的App产品,也在坚持着发表技术博客总结自己所学的东西.在写博客的时候虽然博文中不免有错别字,但每句话都是在斟酌之后所写的,每篇博客所粘贴的代码都是经过调试运行无 ...
- C语言 第七章 数组与字符串
一.数组 1.1.数组的概念 用来存储一组相同类型数据的数据结构.有点像班上放手机的手机袋,超市的储物柜. 特点:只能存放一种类型的数据,如全部是int型或者全部是char型,数组里的数据成为元素. ...
- Anliven - 一碗毒鸡汤
什么是你的核心动力,支撑着你持续前进? 什么是你的加速度,激发你全部的潜能和勇气? 你的核心动力应该来自于: 家人与朋友的信任.包容与期待 你本应承担的责任 对自己有所要求,有所期待,你本应更好 而你 ...
- 到处都是坑的微信支付V3之 微信支付回调页面
据上次 到处都是坑的微信支付V3 后很多园友在被虐了千百遍后终于跳转到了亲切的微信支付界面,但输入密码支付后却不知道怎么处理了,接下来补上支付后的处理流程. 1. html中根据前台支付后反馈信息成功 ...
- Mybatis XML 映射配置文件 -- 熟悉配置
来源:http://www.mybatis.org/mybatis-3/zh/configuration.html properties mybatis读取属性顺序. 如果属性在不只一个地方进行了配置 ...
- 【十大经典数据挖掘算法】k-means
[十大经典数据挖掘算法]系列 C4.5 K-Means SVM Apriori EM PageRank AdaBoost kNN Naïve Bayes CART 1. 引言 k-means与kNN虽 ...
- UWP开发入门(二十二)——Storyboard和Animation
微博上有同学问我MyerSplash是如何实现那个很炫的图片点亮,然后移动到屏幕中央的效果.惭愧啊,我又不是作者哪里会知道.硬着头皮去GitHub拜读了高手的代码,自愧弗如,比我不知道高到哪里去了…… ...
- webControls与客户端脚本路径
网上有用的资料不多,在一本电子书中摘抄了内容如下 webControls配置节只有一个clientScriptsLocation属性,此属性用于指定ASP.NET客户端脚本的默认存放路径.这些文件是包 ...
- SqlServer -- char与varchar、nchar、N
一.char与varchar 带var的表示的是:可变长度,会根据实际存储数据的大小动态重新分配存储空间,相对来说节省存储空间. 不带var的表示的是:固定长度,存储3字符也是要占用10个字节的,会自 ...