Before someone looking for the effect of the gradient progress bar, free to write one, and then draw the view level, easy to explain.
Environmental information:
Mac OS X 10.10.3
Xcode 6.3.1
IOS 8.3
:
Source:
Https://github.com/saitjr/LoopProgressDemo.git
Body
First, the view level
The first thing that needs to be done is the view hierarchy relationship. can see that
1. Background is transparent blue (Blueview)
2. Need a color gradient from green to yellow, the one I used here is layer (Colorlayer)
3. Blueview and Colorlayer Their performance states are ring-shaped, so they need a ring-shaped mask.
4. The blue ring does not change, and the gradient of the ring changes in time, so two masks are required, one for the Blue (Bluemasklayer), one for the gradient (Colormasklayer)
As you can see from the above analysis, several variables and their relationships are now required:
[viewController.view addSubView:blueView];[blueView.layer addSubLayer:colorLayer];colorLayer.mask = colorMaskLayer;blueView.layer.mask = blueMaskLayer;
The view level chart is as follows:
View level diagram
Second, according to the view level to achieve
Figure out the hierarchy, and then it should be implemented one by one.
1. Blue View with transparency 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. Gradient Layer Colorlayer
Because the system does not provide a path based on the implementation of the gradient, it can only be used to draw the way to the salvation of the curve. So the way I'm going to do this is to draw a gradient layer (Leftlayer) on the left that is green and yellow from bottom to top, and then draw a gradient layer (rightlayer) from bottom to top that is red and yellow on the right.
As follows:
Fade color
But the effect is not very good, because the yellow-green and orange-red demarcation is too obvious, so it is better to set a gradient range.
As follows:
To set the gradient color for a fade range
Implementation code:
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);Segment Set Gradient 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/ Span class= "Hljs-number" >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. Circular matte Colormasklayer for gradient layers
Because the ring matte style for the gradient layer ring matte and blue view is the same, you can encapsulate the creation code for the ring mask:
blueview.m
- (Cashapelayer *) Generatemasklayer {Cashapelayer *layer = [Cashapelayer layer]; Layer.frame =Self.bounds;Creates a circle with a center point centered on the parent view, with a radius of 2/5 of the parent view width, starting from -240° to 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; //fill color is transparent (not set to black) Layer.strokecolor = [uicolor BlackColor]. Cgcolor; //arbitrarily set a border color Layer.linecap = Kcalinecapround; //set line for fillet return layer;}
Set the gradient ring matte 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 Ring Mask Bluemasklayer
blueview.m
- (void)setupBlueMaskLayer { CAShapeLayer *layer = [self generateMaskLayer]; self.layer.mask = layer; self.blueMaskLayer = layer;}
5. Set the percentage
Setting the percentage of the gradient is actually changing the range of the Colormasklayer, and the system provides a way to modify it directly based on the percentage.
self.colorMaskLayer.strokeEnd = 0.5;
As a result, the entire effect has been completed, then the rebound animation.
Third, set the rebound animation
I am using the pop library of the popspringanimation, this effect compared to Q-bomb, plus on the progress bar just. To add animation, you just need to change the above Strokeend code changes to the method can be:
- (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"];}
"IOS" Loop gradient progress bar implementation