畫靜態圓的方法有不少,例如UIBezierPath或者UIBezierPath + CAShapeLayer等等,本文也會用到.git
動態效果即不斷的更新圓環的角度(弧度),而後不斷的繪製圓,達到動態效果,使用Quartz2d在drawRect中繪製github
CGContextDrawLinearGradient畫圓,參數CGGradientRef設置漸變色,startPoint和endPoint設置漸變色方向數組
封裝到一個自定義View,快速使用(文章末尾附Demo)bash
手動繪製ide
//1.建立圓環
TYCircleViewConfigure *configure = [[TYCircleViewConfigure alloc]init];
configure.lineColor = [UIColor lightGrayColor];//圓環背景色
configure.circleLineWidth = 10;//圓環寬度
configure.isClockwise = YES;//設置順時針方向畫圓
configure.startPoint = CGPointMake(width / 2, 0);
configure.endPoint = CGPointMake(width / 2 , width);//漸變色分佈方向
//漸變色的顏色
configure.colorArr = @[
(id)TYColorFromRGB(0x349CF7).CGColor,//淺藍色
(id)TYColorFromRGB(0xFE5858).CGColor,//深橙色
(id)TYColorFromRGB(0x72DC4F).CGColor //淺綠色
];
//每一個顏色區域值
configure.colorSize = @[@0,@0.3,@0.8];
TYCircleView *circleView = [[TYCircleView alloc]initWithFrame:CGRectMake(x , y, width, width) configure:configure];
[self.view addSubview:circleView];
複製代碼
自動繪製動畫
1.文件.h中建立須要用到的屬性的配置類ui
//配置屬性
/********************* TYCircleViewConfigure ************************/
@interface TYCircleViewConfigure : NSObject
/** 圓環線條寬度 */
@property (nonatomic, assign) CGFloat circleLineWidth;
/** 圓環的顏色 */
@property (nonatomic, strong) UIColor *lineColor;
/** 是不是順時針 默認是NO:逆時針 */
@property (nonatomic, assign) BOOL isClockwise;
/** 漸變色方向 起始座標 */
@property (nonatomic, assign) CGPoint startPoint;
/** 漸變色方向 結束座標 */
@property (nonatomic, assign) CGPoint endPoint;
/** 漸變色的顏色數組 */
@property (nonatomic, strong) NSArray *colorArr;
/** 每一個顏色的起始位置數組 注:每一個元素 0 <= item < 1 */
@property (nonatomic, strong) NSArray *colorSize;
//注意: colorArr.count 和 colorSize.count 必須相等
//不相等時,漸變色最終顯示出來的樣子和指望的會有差別
@end
複製代碼
- 繪製灰色的背景圓環
//繪製背景圓
- (void)drawBackCircleView {
//1.UIBezierPath建立一個圓環路徑
//圓心
CGPoint arcCenter = CGPointMake(self.frame.size.width/2.0, self.frame.size.height/2.0);
//半徑 , circleLineWidth = 圓環線條寬度
CGFloat radius = (self.frame.size.width - _configure.circleLineWidth)/2.0;
//開始弧度:-M_PI_2,豎直向上; 結束弧度:-M_PI_2 + M_PI*2,一圈 clockwise:YES逆時針 NO順時針
//clockwise = NO時,若結束弧度 = -M_PI_2 + M_PI*2, 則圓環消失歸零
UIBezierPath *circle = [UIBezierPath bezierPathWithArcCenter:arcCenter radius:radius startAngle:-M_PI_2 endAngle:-M_PI_2 + M_PI*2 clockwise:YES];
//2.建立一個ShapeLayer
CAShapeLayer *bgLayer = [CAShapeLayer layer];
bgLayer.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.width);
bgLayer.fillColor = [UIColor clearColor].CGColor;//圓環路徑填充顏色
bgLayer.lineWidth = _configure.circleLineWidth;//圓環寬度
bgLayer.strokeColor = _configure.lineColor.CGColor;//路徑顏色
bgLayer.strokeStart = 0.f;//路徑開始位置
bgLayer.strokeEnd = 1.f;//路徑結束位置
bgLayer.path = circle.CGPath;
//3.把路徑設置到layer上,換出背景圓環
[self.layer addSublayer:bgLayer];
}
複製代碼
3.在TYDrawCircleView的實現中,重寫drawRect,繪製圓環atom
- (void)drawRect:(CGRect)rect {
//獲取圖形上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
//設置線的寬度
CGContextSetLineWidth(ctx, _configure.circleLineWidth);
//設置圓環線條的兩個端點作圓滑處理
CGContextSetLineCap(ctx, kCGLineCapRound);
//設置畫筆顏色
CGContextSetFillColorWithColor(ctx, [UIColor blackColor].CGColor);
//設置圓心
CGFloat originX = rect.size.width / 2;
CGFloat originY = rect.size.height / 2;
//計算半徑
CGFloat radius = MIN(originX, originY) - _configure.circleLineWidth/2.0;
//創建一個最小初始弧度值,避免進度progress爲0或1時圓環消失
CGFloat minAngle = M_PI/90 - self.progress * M_PI/80;
//逆時針畫一個圓弧
if (self.configure.isClockwise) {
CGContextAddArc(ctx, rect.size.width / 2, rect.size.height / 2, radius, -M_PI_2, -M_PI_2 + minAngle + (2 * M_PI)*self.progress, NO);
}else{
CGContextAddArc(ctx, rect.size.width / 2, rect.size.height / 2, radius, -M_PI_2, -M_PI_2 - minAngle + (2 * M_PI)*(1-self.progress), YES);
}
//2. 建立一個漸變色
CGFloat locations[_configure.colorSize.count];
for (NSInteger index = 0; index < _configure.colorSize.count; index++) {
locations[index] = [_configure.colorSize[index] floatValue];
}
//建立RGB色彩空間,建立這個之後,context裏面用的顏色都是用RGB表示
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace,(__bridge CFArrayRef _Nonnull)_configure.colorArr, _configure.colorSize.count==0?NULL:locations);
//釋放色彩空間
CGColorSpaceRelease(colorSpace);
colorSpace = NULL;
//3.畫出圓環路徑
CGContextReplacePathWithStrokedPath(ctx);
//剪裁路徑
CGContextClip(ctx);
//4.用漸變色填充,修改填充色的方向
CGContextDrawLinearGradient(ctx, gradient, _configure.startPoint, _configure.endPoint, 1);
//釋放漸變色
CGGradientRelease(gradient);
}
複製代碼
- 動態畫圓
- (void)setProgress:(CGFloat)progress {
_progress = progress;
_circleView.progress = progress;
[_circleView setNeedsDisplay]; //重繪TYDrawCircleView,即調用TYDrawCircleView的DrawRect方法
}
複製代碼
咱們在TYDrawCircleView的重DrawRect方法中用CGContextDrawLinearGradient方法來畫出圓環,並設置圓環的漸變色gradient和漸變色分佈方向, startPoint即漸變色的起始點位置, endPoint即漸變色的終點位置 spa
//width = 圓的直徑
configure.startPoint = CGPointMake(width / 2, 0);
configure.endPoint = CGPointMake(width / 2 , width);//漸變色分佈方向
複製代碼
咱們設置tartPoint = CGPointMake(width / 2, 0)即點A的位置,configure.endPoint = CGPointMake(width / 2 , width)即點B的位置,其餘位置的話你們能夠自行嘗試code
咱們在"使用"中,設置了三種漸變色
//漸變色的顏色
configure.colorArr = @[
(id)TYColorFromRGB(0x349CF7).CGColor,//淺藍色
(id)TYColorFromRGB(0xFE5858).CGColor,//深橙色
(id)TYColorFromRGB(0x72DC4F).CGColor //淺綠色
];
複製代碼
在不設置configure.colorSize (每一個顏色區域值)時,三個顏色根據漸變色方向,依次均等分佈 當咱們不須要三個顏色均等分佈時,能夠經過設置configure.colorSize分別給三個顏色設置起始位置和結束位置
//每一個顏色區域值
configure.colorSize = @[@0,@0.3,@0.8];
複製代碼
1.關於其餘解釋代碼中的註釋也比較詳細,有不懂的地方能夠留言和我交流
2.Demo地址:github.com/TynnPassBy/…
3.碼字不易,若是幫助到你得話,請點個贊吧~