1、绘制下载进度按钮
具体实现代码见 GitHub 源码 QExtension
-
QProgressButton.h
@interface QProgressButton : UIButton /// 进度值,范围 0 ~ 1 @property (nonatomic, assign) CGFloat progress; /// 进度终止状态标题,一旦设置了此标题进度条就会停止 @property (nonatomic, strong) NSString *stopTitle; /** * 创建带进度条的按钮 * * @param frame 按钮的 frame 值 * @param title 进按钮的标题 * @param lineWidth 进度条的线宽,default is 2 * @param lineColor 进度条线的颜色,default is greenColor * @param textColor 进度值的颜色,default is blackColor * @param backColor 按钮的背景颜色,default is clearColor * @param isRound 按钮是否显示为圆形,default is YES * * @return 带进度条的按钮 */ + (instancetype)q_progressButtonWithFrame:(CGRect)frame title:(NSString *)title lineWidth:(CGFloat)lineWidth lineColor:(nullable UIColor *)lineColor textColor:(nullable UIColor *)textColor backColor:(nullable UIColor *)backColor isRound:(BOOL)isRound; @end
-
QProgressButton.m
@interface QProgressButton () /// 进度条的线宽 @property (nonatomic, assign) CGFloat lineWidth; /// 进度条线的颜色 @property (nonatomic, strong) UIColor *lineColor; /// 按钮的背景颜色 @property (nonatomic, strong) UIColor *backColor; /// 按钮是否显示为圆形 @property (nonatomic, assign, getter=isRound) BOOL round; @end @implementation QProgressButton /// 创建带进度条的按钮 + (instancetype)q_progressButtonWithFrame:(CGRect)frame title:(NSString *)title lineWidth:(CGFloat)lineWidth lineColor:(nullable UIColor *)lineColor textColor:(nullable UIColor *)textColor backColor:(nullable UIColor *)backColor isRound:(BOOL)isRound { QProgressButton *progressButton = [[self alloc] init]; progressButton.lineWidth = lineWidth ? : 2; progressButton.lineColor = lineColor ? : [UIColor colorWithRed:76/255.0 green:217/255.0 blue:100/255.0 alpha:1.0]; progressButton.backColor = backColor ? : [UIColor clearColor]; progressButton.round = isRound; // 设置按钮的实际 frame if (isRound) { CGRect tmpFrame = frame; tmpFrame.origin.y = frame.origin.y - (frame.size.width - frame.size.height) * 0.5; tmpFrame.size.height = frame.size.width; progressButton.frame = tmpFrame; } else { progressButton.frame = frame; } // 设置显示的标题和颜色 [progressButton setTitle:title forState:UIControlStateNormal]; [progressButton setTitleColor:(textColor ? : [UIColor blackColor]) forState:UIControlStateNormal]; return progressButton; } /// 绘制进度条 - (void)drawRect:(CGRect)rect { // 设置按钮圆角 self.layer.masksToBounds = YES; self.layer.cornerRadius = rect.size.height * 0.5; // 绘制按钮的背景颜色 UIBezierPath *path = [UIBezierPath bezierPathWithRect:rect]; [self.backColor set]; [path fill]; // 设置进度终止时显示的内容 if (self.stopTitle) { // 设置下载完成后的标题 [self setTitle:self.stopTitle forState:UIControlStateNormal]; return; } if (self.progress <= 0) { return; } // 清除按钮背景图片 [self setBackgroundImage:nil forState:UIControlStateNormal]; // 设置进度值 [self setTitle:[NSString stringWithFormat:@"%.2f%%", self.progress * 100] forState:UIControlStateNormal]; if (self.isRound) { CGPoint center = CGPointMake(rect.size.height * 0.5, rect.size.height * 0.5); CGFloat radius = (rect.size.height - self.lineWidth) * 0.5; CGFloat startA = - M_PI_2; CGFloat endA = startA + self.progress * 2 * M_PI; // 绘制进度条背景 path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:0 endAngle:2 * M_PI clockwise:YES]; [[[UIColor lightGrayColor] colorWithAlphaComponent:0.5] set]; path.lineWidth = self.lineWidth; [path stroke]; // 绘制进度条 path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startA endAngle:endA clockwise:YES]; path.lineWidth = self.lineWidth; path.lineCapStyle = kCGLineCapRound; [self.lineColor set]; [path stroke]; } else { CGFloat w = self.progress * rect.size.width; CGFloat h = rect.size.height; // 绘制进度条背景 path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, rect.size.width, rect.size.height)]; [[[UIColor lightGrayColor] colorWithAlphaComponent:0.5] set]; [path fill]; // 绘制进度条 path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, w, h)]; [self.lineColor set]; [path fill]; } } /// 设置进度值 - (void)setProgress:(CGFloat)progress { _progress = progress; [self setNeedsDisplay]; } /// 设置进度终止状态标题 - (void)setStopTitle:(NSString *)stopTitle { _stopTitle = stopTitle; [self setNeedsDisplay]; } @end
-
ViewController.m
// 创建进度按钮 QProgressButton *progressButton = [QProgressButton q_progressButtonWithFrame:CGRectMake(100, 100, 100, 50) title:@"开始下载" lineWidth:10 lineColor:[UIColor blueColor] textColor:[UIColor redColor] backColor:[UIColor yellowColor] isRound:YES]; // 设置按钮点击事件 [progressButton addTarget:self action:@selector(progressUpdate:) forControlEvents:UIControlEventTouchUpInside]; // 将按钮添加到当前控件显示 [self.view addSubview:progressButton]; // 设置按钮的进度值 self.progressButton.progress = progress; // 设置按钮的进度终止标题,一旦设置了此标题进度条就会停止 self.progressButton.stopTitle = @"下载完成";
-
效果