iOS arc gradual progress of implementation

Since the project requires a gradual progress bar shows the ring course, this convenience does have a lot of relevant information online, however, are more fragmented and, most just put a bunch of code is even finished. Here I would like to write my own detailed implementation of this process progress bar.

Arc achieved a progress bar is divided into three steps
a, Videos Bezier arc used herein, what is this: UIBezierPath
two, according to two arcs Videos Bezier curves a path above a background fill color , is used in this class CAShapeLayer.h
Third, draw two color gradient, to map the progress of the above paths to the gradient color, gradient color used is this thing CAGradientLayer.h

Target effect is shown


AirPlay_Movie_2017-11-29_04-42-48.gif

first step:

  • We unbundled pattern is superimposed on a circle on top of a ring, the ring is a gray background, while the upper ring is a custom color.
    • First, we draw a circle, in fact, a rough circle, with UIBezierPath here to draw.
      Results pictures:



      Code:

    //贝塞尔曲线画圆弧
      UIBezierPath *circlePath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.width / 2, self.height / 2) radius:(self.width - 20)/2 startAngle:0 endAngle:2 * M_PI clockwise:YES]; //设置颜色 [[UIColor blackColor] set]; //线粗细 circlePath.lineWidth = 10; //开始绘图 [circlePath stroke]; 

Here mainly to pay attention to this method:

+ (instancetype)bezierPathWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise; 

Five parameters are
center: center
radius: Radius
startAngle: starting angle
endAngle: ending angle
clockwise: Paint whether clockwise
major and difficult to understand startAngle endAngle

Such provisions in the official documents of the OC:
Official documents drawn arc .jpg

So I need to draw an arc goal from 3π / 4 to start 1π / 4 End
method with the following:

UIBezierPath *circlePath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.width / 2, self.height / 2) radius:(self.width - 20)/2 startAngle:M_PI / 4 + M_PI / 2 endAngle:M_PI / 4 clockwise:YES]; 

Renderings:


Black circular path .jpg

Step two:

  • The first step in the path drawn by CAShapeLayer Videos good layer to layer up
    to Videos Gray circle:
    CAShapeLayer *bgLayer = [CAShapeLayer layer];
    bgLayer.frame = self.bounds;
    bgLayer.fillColor = [UIColor clearColor].CGColor;//填充色 - 透明 bgLayer.lineWidth = 20.f; bgLayer.strokeColor = ZCCRGBColor(212, 212, 212, 1.0).CGColor;//线条颜色 bgLayer.strokeStart = 0;//起始点 bgLayer.strokeEnd = 1;//终点 bgLayer.lineCap = kCALineCapRound;//让线两端是圆滑的状态 bgLayer.path = circlePath.CGPath;//这里就是把背景的路径设为之前贝塞尔曲线的那个路径 [self.layer addSublayer:bgLayer]; 

Renderings:


Curved progress bar background color .jpg
  • Draw the progress bar arc
_shapeLayer = [CAShapeLayer layer];
    _shapeLayer.frame = self.bounds;
    _shapeLayer.fillColor = [UIColor clearColor].CGColor;
    _shapeLayer.lineWidth = 20.f;
    _shapeLayer.lineCap = kCALineCapRound;
// _shapeLayer.strokeColor = color.CGColor; _shapeLayer.strokeColor = [UIColor blueColor].CGColor; _shapeLayer.strokeStart = 0; _shapeLayer.strokeEnd = 0.8; _shapeLayer.path = circlePath.CGPath; [self.layer addSublayer:_shapeLayer]; 
The above is roughly the same code and change it there strokenEnd color attributes make progress is not completely full, the effect is as follows:
The blue bar .jpg

The third step:
This completes the two-step basis. Now is the most troublesome gradient of this one. First, become familiar with the process of gradient layer class, CAGradientLayer this is a subclass layer, I direct that these examples speak the language

//初始化一个渐变图层
    CAGradientLayer *leftGradientLayer = [CAGradientLayer layer];
//设frame
    leftGradientLayer.frame = CGRectMake(0, 0, self.width / 2, self.height); //设渐变颜色 //ZCCRGBColor是我自定义的宏 #define ZCCRGBColor(a,b,c,al) [UIColor colorWithRed:a/255.0 green:b/255.0 blue:c/255.0 alpha:al] [leftGradientLayer setColors:[NSArray arrayWithObjects:(id)ZCCRGBColor(255, 255, 0, 1).CGColor, (id)ZCCRGBColor(255, 0, 0, 1).CGColor, nil]]; //这里设置渐变色渐变范围 0到1就是整个leftGradientLayer上都在渐变 [leftGradientLayer setLocations:@[@0,@1]]; //下面这两个就是渐变色方向Y越大就是越下面 所以是从下到上从黄到红渐变 [leftGradientLayer setStartPoint:CGPointMake(0, 1)]; [leftGradientLayer setEndPoint:CGPointMake(0, 0)]; 添加到父图层 [_gradientLayer addSublayer:leftGradientLayer]; 
Look at the renderings
Left from bottom to top gradient layer .jpg

Modify this method

 [leftGradientLayer setLocations:@[@0,@0.5]];

Renderings:


Only half of the gradient .jpg

Only one side of the upper half of all red gradient.

Modify the primary control this property gradient direction

     [leftGradientLayer setLocations:@[@0,@1]];
    [leftGradientLayer setStartPoint:CGPointMake(0, 1)];
    [leftGradientLayer setEndPoint:CGPointMake(1, 0)];

Such is the diagonal gradient is as follows:


Diagonal gradient .jpg

Doing so a simple dot gradient is a ring and the ring to set the same width and height as FIG.


Gradient piece .jpg

Then add the following lines of code which can be mapped to a color gradient layer to layer above the ring

[self.gradientLayer setMask:_shapeLayer];

Renderings


Diagonal gradient arc .jpg

But in fact there is a problem here, when the arc when you can see the full schedule below:


Diagonal gradient whole arc .jpg

You can see the bottom right corner of the picture above is not so red it is not a true gradient. So in the end how to do it rings true gradient?

In fact, just started painting above the gradient layer when I buried a foreshadowing.

And painstakingly tested several properties that gradient layer, in fact, to the following effect:
Gradient layers around .jpg
Is then mapped to the effect that FIG arc:
Around the circular-arc block mapping gradient .jpg

In fact, there is a problem here is that the top of the excessive there will be a significant fault
so we will use [leftGradientLayer setLocations: @ [@ 0 , @ 0.5]]; this property is set gradient range. Let the top of the gradient color basic fixed

左边的渐变色块:
[leftGradientLayer setLocations:@[@0,@0.9]];
右边的渐变色块:
[rightGradientLayer setLocations:@[@0.1, @1]];

Look at renderings


Pictures .png

Well, this is almost a complete gradient arc, and obsessive-compulsive disorder if a friend can actually get four color gradient from the lower left → upper left → upper right → lower right followed by gradual re-mapped, so it will be more perfect.

Finally finished. . Novice first time to write such a teaching text of what is wrong places vexed pointed out, do not know how you can leave a message asking me

Finally, the animation is how to achieve it? ?
This is achieved by timer setting _shapeLayer.strokeEnd strokEnd properties achieved
following is a specific code ~

- (void)animateToProgress:(CGFloat)progress{
    
//    NSLog(@"增加到progress%lf", progress);
    
    if(_shapeLayer.strokeEnd != 0){ [self animateToZero]; } __weak typeof(self)weakSelf = self; NSLog(@"-----%lf",_shapeLayer.strokeEnd); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(_shapeLayer.strokeEnd * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [weakSelf deleteTimer]; NSString *progressStr = [NSString stringWithFormat:@"%lf",progress]; NSDictionary *userInfo = @{@"progressStr":progressStr}; weakSelf.timer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:weakSelf selector:@selector(animate:) userInfo:userInfo repeats:YES]; }); } - (void)animate:(NSTimer *)time{ CGFloat progress = [[time.userInfo objectForKey:@"progressStr"] floatValue]; if(_shapeLayer.strokeEnd <= progress) { _shapeLayer.strokeEnd += 0.01; }else{ [self deleteTimer]; } } //回滚到0 先判断 timer 有没有存在 存在 就把timer 删除 - (void)animateToZero{ // NSLog(@"删除到0"); [self deleteTimer]; self.timer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(animateReset) userInfo:nil repeats:YES]; } - (void)animateReset{ if(_shapeLayer.strokeEnd > 0){ _shapeLayer.strokeEnd -= 0.01; }else{ [self deleteTimer]; } } - (void)deleteTimer{ [self.timer invalidate]; self.timer = nil; } 

The complete code gitHub link



Author: zcc_ios
link: https: //www.jianshu.com/p/edbc647ff178
Source: Jane book
Jane book copyright reserved by the authors, are reproduced in any form, please contact the author to obtain authorization and indicate the source.

Guess you like

Origin www.cnblogs.com/Free-Thinker/p/11124510.html
arc