繪制扇形進(jìn)度條
背景:上傳文件的時(shí)候闪水,需要有上傳進(jìn)度报破,這次需要一個(gè)扇形的進(jìn)度條,示例圖如下:
背景.jpg
廢話不多說蚤吹,上代碼:
/**
扇形圖進(jìn)度條
角度:可選擇起始角度:SLSectorStartAngle:top left bottom and right
旋轉(zhuǎn):順時(shí)針旋轉(zhuǎn)
半徑:radius
填充色:fillColor
*/
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSUInteger, SLSectorStartAngle) {
SLSectorStartAngle_top = 0,
SLSectorStartAngle_left,
SLSectorStartAngle_bottom,
SLSectorStartAngle_right,
};
@interface SLSectorProgressBar : UIView
/// 構(gòu)造方法
/// @param startAngle 初始角度
- (instancetype)initWithStartAngle:(SLSectorStartAngle)startAngle radius:(CGFloat)radius fillColor:(UIColor *)fillColor;
/// 進(jìn)度
@property(nonatomic, assign) CGFloat progress;
/// 配置邊框顏色和寬度
/// @param borderColor 邊框顏色
/// @param borderWidth 邊框?qū)挾?- (void)configBorderWithColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth;
/// 沒有進(jìn)度時(shí)例诀,是否需要占位線(如果需要下面的繪制外圈的圓圈,一般都需要繪制默認(rèn)占位線)
@property (nonatomic, assign) BOOL needPlaceholderLine;
@end
#import "SLSectorProgressBar.h"
@interface SLSectorProgressBar ()
/// 開始角度
@property (nonatomic, assign) SLSectorStartAngle startAngle;
/// 半徑
@property (nonatomic, assign) CGFloat radius;
/// 填充色
@property (nonatomic, strong) UIColor *fillColor;
/// 邊框顏色
@property (nonatomic, strong) UIColor *borderColor;
/// 邊框粗細(xì)
@property (nonatomic, assign) CGFloat borderWidth;
@end
@implementation SLSectorProgressBar
- (instancetype)initWithStartAngle:(SLSectorStartAngle)startAngle radius:(CGFloat)radius fillColor:(UIColor *)fillColor {
if (self = [super init]) {
self.backgroundColor = [UIColor clearColor];
_startAngle = startAngle;
_radius = radius ?: 200;
_fillColor = fillColor ?: [UIColor cyanColor];
}
return self;
}
- (void)configBorderWithColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth {
_borderColor = borderColor;
_borderWidth = borderWidth;
}
#pragma mark - 更新進(jìn)度
- (void)setProgress:(CGFloat)progress{
_progress = progress;
[self setNeedsDisplay];
}
#pragma mark - 繪制圖形
- (void)drawRect:(CGRect)rect {
[self drawLine];
[self drawProgress];
}
// 繪制外圈線條
- (void)drawLine {
CGPoint origin = CGPointMake(_radius/2, _radius/2);
CGFloat radius = _radius/2 - _borderWidth/2;
CGFloat startAngle = 0;
CGFloat endAngle = 2*M_PI;
UIBezierPath *sectorPath = [UIBezierPath bezierPathWithArcCenter:origin radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];
if (self.needPlaceholderLine) {
[sectorPath moveToPoint:origin];
[sectorPath addLineToPoint:CGPointMake(_radius/2, 0)];
}
sectorPath.lineWidth = _borderWidth;
[_borderColor set];
[sectorPath strokeWithBlendMode:kCGBlendModeNormal alpha:1.0];
}
// 繪制進(jìn)度條
- (void)drawProgress {
// 中心點(diǎn)
CGPoint origin = CGPointMake(_radius/2, _radius/2);
// 半徑
CGFloat radius = _radius/2;
// 起始角度
CGFloat startAngle = [self fetchStartAngle];
// 結(jié)束角度
CGFloat endAngle = [self fetchEndAngle];
// 開始繪制
UIBezierPath *sectorPath = [UIBezierPath bezierPathWithArcCenter:origin radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];
[sectorPath addLineToPoint:origin];
[_fillColor set];
[sectorPath fill];
}
#pragma mark - Tools
- (CGFloat)fetchStartAngle {
CGFloat angle = - M_PI_2; // 默認(rèn)top
switch (_startAngle) {
case SLSectorStartAngle_left:
angle = M_PI;
break;
case SLSectorStartAngle_bottom:
angle = M_PI_2;
break;
case SLSectorStartAngle_right:
angle = M_PI * 2;
break;
default:
break;
}
return angle;
}
- (CGFloat)fetchEndAngle {
CGFloat angle = [self fetchStartAngle] + self.progress * M_PI * 2;
return angle;
}
@end
以上代碼的調(diào)用方式如下:
#import "ViewController.h"
#import "SLSectorProgressBar.h"
@interface ViewController ()
@property (nonatomic, strong) UISlider *slider;
@property (nonatomic, strong) SLSectorProgressBar *sectorView;
@property (nonatomic, strong) UIColor *testColor;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.testColor = [UIColor redColor];
[self.view addSubview:self.slider];
[self.view addSubview:self.sectorView];
}
- (void)sliderValueChange:(UISlider *)sender {
self.sectorView.progress = (sender.value - sender.minimumValue) / (sender.maximumValue - sender.minimumValue);
}
- (UISlider *)slider {
if (_slider == nil) {
_slider = [[UISlider alloc] initWithFrame:CGRectMake(50, 100, self.view.frame.size.width - 100, 50)];
[_slider addTarget:self action:@selector(sliderValueChange:) forControlEvents:UIControlEventValueChanged];
[_slider setMinimumTrackTintColor:self.testColor];
}
return _slider;
}
- (SLSectorProgressBar *)sectorView {
if (_sectorView == nil) {
_sectorView = [[SLSectorProgressBar alloc] initWithStartAngle:SLSectorStartAngle_top radius:200 fillColor: self.testColor];
[_sectorView configBorderWithColor:[UIColor colorWithRed:0 green:0 blue:0 alpha:0.1] borderWidth:3];
_sectorView.progress = 0;
CGFloat wh = 200;
CGFloat y = CGRectGetMaxY(self.slider.frame) + 10;
CGFloat x = (self.view.frame.size.width - wh) / 2;
_sectorView.frame = CGRectMake(x, y, wh, wh);
}
return _sectorView;
}
@end
按照上面代碼跑起來裁着,示例圖如下:
demo.jpg