【iOS】环形渐变进度条实现

之前有人在找渐变进度条的效果,闲来无事就顺手写了一个,然后画了视图层级,方便讲解。

环境信息:

Mac OS X 10.10.3

Xcode 6.3.1

iOS 8.3

效果图:

源码下载地址:

https://github.com/saitjr/LoopProgressDemo.git

正文

一、视图层级

首先需要搞定的就是视图层级关系。可以看到,

1. 背景是有透明度的蓝色(blueView)

2. 需要一个从绿->黄->红的渐变色,那个这里我采用的是Layer(colorLayer)

3. blueView和colorLayer他们的表现状态都是环形的,所以还需要环形的遮罩

4. 蓝色的环并没有变,而渐变色的环却在时刻变化,所以需要两个遮罩,一个给蓝色(blueMaskLayer),一个给渐变色(colorMaskLayer)

从上面的分析可以看出,现在需要几个变量以及他们的关系如下:

[viewController.view addSubView:blueView];
[blueView.layer addSubLayer:colorLayer];
colorLayer.mask = colorMaskLayer;
blueView.layer.mask = blueMaskLayer;

视图层级图如下:

视图层级图

二、根据视图层级来实现

搞清楚了层级,接着就应该逐个实现了。

1. 有透明度的蓝色视图blueView

ViewController.m

BlueView *blueView = [[BlueView alloc] initWithFrame:CGRectMake(0, 0, 300, 300)];
blueView.center = self.view.center;
blueView.backgroundColor = [UIColor blueColor]; // 我这里没有给透明度
[self.view addSubView:blueView];

2. 渐变图层colorLayer

因为系统没有提供根据路径渐变的实现方法,所以只能采用曲线救国的方式来画。那么我所使用的方法是:在左边画一个从下往上为绿->黄的渐变Layer(leftLayer),然后右边画一个从下往上为红->黄的渐变Layer(rightLayer)。

效果图如下:

渐变色

但是这种方式效果不是很好,因为黄绿色和橘红色的分界太明显,所以最好设置一个渐变的范围。

效果图如下:

设置渐变范围的渐变色

实现代码:

BlueView.m

- (void)setupColorLayer {
    self.colorLayer = [CAShapeLayer layer];
    self.colorLayer.frame = self.bounds;
    [self.layer addSublayer:self.colorLayer];

    CAGradientLayer *leftLayer = [CAGradientLayer layer];
    leftLayer.frame = CGRectMake(0, 0, self.bounds.size.width / 2, self.bounds.size.height);
    // 分段设置渐变色
    leftLayer.locations = @[@0.3, @0.9, @1];
    leftLayer.colors = @[(id)[UIColor yellowColor].CGColor, (id)[UIColor greenColor].CGColor];
    [self.colorLayer addSublayer:leftLayer];

    CAGradientLayer *rightLayer = [CAGradientLayer layer];
    rightLayer.frame = CGRectMake(self.bounds.size.width / 2, 0, self.bounds.size.width / 2, self.bounds.size.height);
    rightLayer.locations = @[@0.3, @0.9, @1];
    rightLayer.colors = @[(id)[UIColor yellowColor].CGColor, (id)[UIColor redColor].CGColor];
    [self.colorLayer addSublayer:rightLayer];
}

3. 渐变图层的环形遮罩colorMaskLayer

因为渐变图层环形遮罩和蓝色视图的环形遮罩样式都是一样的,所以可以将环形遮罩的创建代码封装出来:

BlueView.m

- (CAShapeLayer *)generateMaskLayer {

    CAShapeLayer *layer = [CAShapeLayer layer];
    layer.frame = self.bounds;

    // 创建一个圆心为父视图中点的圆,半径为父视图宽的2/5,起始角度是从-240°到60°
    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.bounds.size.width / 2, self.bounds.size.height / 2) radius:self.bounds.size.width / 2.5 startAngle:-3 / 4 * M_PI endAngle:1 / 3 * M_PI clockwise:YES];
    layer.lineWidth = 20;
    layer.path = path.CGPath;
    layer.fillColor = [UIColor clearColor].CGColor; // 填充色为透明(不设置为黑色)
    layer.strokeColor = [UIColor blackColor].CGColor; // 随便设置一个边框颜色
    layer.lineCap = kCALineCapRound; // 设置线为圆角
    return layer;
}

设置渐变色环形遮罩层

BlueView.m

- (void)setupColorMaskLayer {

    CAShapeLayer *layer = [self generateMaskLayer];
    layer.lineWidth = 20.5; // 渐变遮罩线宽较大,防止蓝色遮罩有边露出来
    self.colorLayer.mask = layer;

    self.colorMaskLayer = [CAShapeLayer layer];
    self.colorMaskLayer = layer;
}

4. blueView的环形遮罩blueMaskLayer
BlueView.m

- (void)setupBlueMaskLayer {

    CAShapeLayer *layer = [self generateMaskLayer];
    self.layer.mask = layer;
    self.blueMaskLayer = layer;
}

5. 设置百分比

设置渐变色所占的百分比,其实就是改变colorMaskLayer的范围,系统提供了一个方法可以直接根据百分比来修改。

self.colorMaskLayer.strokeEnd = 0.5;

到此,整个效果就已经完成了,接下来说一下回弹动画。

三、设置回弹动画

我所使用的是pop库中的POPSpringAnimation,这个效果比较Q弹,加在进度条上刚好。要加动画,只需要把上面的修改strokeEnd的代码换成一下方法就可以了:

- (void)animationWithStrokeEnd:(CGFloat)strokeEnd {

    POPSpringAnimation *strokeAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPShapeLayerStrokeEnd];
    strokeAnimation.toValue = @(strokeEnd);
    strokeAnimation.springBounciness = 12.f;
    strokeAnimation.removedOnCompletion = NO;
    [self.colorMaskLayer pop_addAnimation:strokeAnimation forKey:@"layerStrokeAnimation"];
}
时间: 2024-10-12 04:38:20

【iOS】环形渐变进度条实现的相关文章

svg和css3创建环形渐变进度条

在负责的项目中,有一个环形渐变读取进度的效果的需求,于是在网上查阅相关资料整理一下.代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://code.jquery.com/jquery-3.1.1.min.js&qu

自定义控件之圆形颜色渐变进度条--SweepGradient

前几天在群里面有人找圆形可颜色渐变进度条,其中主要的知识点是SweepGradient: mSweepGradient = new SweepGradient(240, 360, new int[] { Color.CYAN, Color.DKGRAY, Color.GRAY, Color.LTGRAY, Color.MAGENTA, Color.GREEN, Color.TRANSPARENT, Color.BLUE }, null); 如上:第三个参数为渐变颜色内容,前两个是坐标信息,240

Xamarin iOS教程之进度条和滚动视图

Xamarin iOS教程之进度条和滚动视图 Xamarin iOS 进度条 进度条可以看到每一项任务现在的状态.例如在下载的应用程序中有进度条,用户可以很方便的看到当前程序下载了多少,还剩下多少.QQ音乐播放器中也使用到了进度条,它可以让用户看到当前音乐播放了多少,还剩多少等.在Xamarin.iOS中也提供实现进度条的类,即UIProgressView. [示例2-23]以下将实现进度条加载的效果.具体步骤如下: (1)创建一个Single View Application类型的工程,命名为

iOS 渐变进度条

#import <UIKit/UIKit.h> @interface JianBianView : UIView //为了增加一个表示进度条的进行,可们可以使用mask属性来屏蔽一部分 @property (nonatomic, strong) CALayer *maskLayer; @property (nonatomic, assign) CGFloat progress; //动画方法 -(void)performAnimation; -(void)setProgress:(CGFloa

纯CSS3实现苹果iOS 7风格进度条

还记得iOS 7的“颠覆性”扁平化设计吗?其中的各种扁平化UI界面都让我们为之惊叹,其中的进度条更是让人喜欢 的不得了.今天就给大家分享一个用CSS3制作的iOS7进度条小教程,这是一款非常优秀的UI交互设计.下面就来看看演示效果以及实现方式吧! HTML结构代码 首先设计HTML的基本结构,大概如下: <div class="container"> <h1 class="text-center">iOS 7进度条</h1> &l

android自定义渐变进度条

</pre>       项目中需要用到一个弧形渐变的进度条,通过android自带是不能实现的,我是没有找到实现的方法,有大神知道的可以指点,效果图是下面这样的<p></p><p><img src="" alt="" /><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAbcAAAClCAYAAADf/rPPAAAgAElEQ

android自己定义渐变进度条

项目中须要用到一个弧形渐变的进度条,通过android自带是不能实现的.我是没有找到实现的方法,有大神知道的能够指点.效果图是以下这种 这是通过继承VIew来绘制出来的,网上也有相似的,可是代码那是相当的累赘,并且创建了非常多没用的对象,给内存管理带来负担? ?? 我在这把自己定义的View代码贴出来了,用到的话能够加以參考 public class SpringProgressView extends View { /** * 分段颜色 */ private static final int[

iOS 贝赛尔 圆形进度条

UIBezierPath *aPth = [UIBezierPath bezierPathWithArcCenter:CGPointMake(55, 65.f) radius:50.f startAngle:-M_PI_2 endAngle:M_PI_2 clockwise:YES]; aPth.lineWidth = 5.0f; aPth.lineCapStyle = kCGLineCapRound; aPth.lineJoinStyle = kCGLineJoinRound; [[UICol

iOS-Quart2D 进度条

// // HMProgressView.h // 进度条 // // Created by YaguangZhu on 15/9/9. // Copyright (c) 2015年 YaguangZhu. All rights reserved. // #import <UIKit/UIKit.h> @interface HMProgressView : UIView @property(nonatomic,assign)CGFloat progress; @end // // HMProg