iOS - Quartz 2D 下载进度按钮绘制

简介: 1、绘制下载进度按钮具体实现代码见 GitHub 源码 QExtensionQProgressButton.h @interface QProgressButton : UIButton /// 进度值,范围 0 ~ 1 @property (nonatomic, ...

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 = @"下载完成";
  • 效果

    Quartz2D44Quartz2D45

    Quartz2D46Quartz2D47

目录
相关文章
|
iOS开发
iOS MFMessageComposeViewController不显示取消按钮,导航条上白色,无取消按钮,无法返回应用...
iOS MFMessageComposeViewController不显示取消按钮,导航条上白色,无取消按钮,无法返回应用...
67 0
|
23天前
|
Swift iOS开发 UED
如何使用Swift和UIKit在iOS应用中实现自定义按钮动画
本文通过一个具体案例,介绍如何使用Swift和UIKit在iOS应用中实现自定义按钮动画。当用户点击按钮时,按钮将从圆形变为椭圆形,颜色从蓝色渐变到绿色;释放按钮时,动画以相反方式恢复。通过UIView的动画方法和弹簧动画效果,实现平滑自然的过渡。
40 1
|
1月前
|
Swift iOS开发 UED
如何使用Swift和UIKit在iOS应用中实现自定义按钮动画
【10月更文挑战第18天】本文通过一个具体案例,介绍如何使用Swift和UIKit在iOS应用中实现自定义按钮动画。当用户按下按钮时,按钮将从圆形变为椭圆形并从蓝色渐变为绿色;释放按钮时,动画恢复原状。通过UIView的动画方法和弹簧动画效果,实现平滑自然的动画过渡。
50 5
|
6月前
|
iOS开发
iOS13.6.1系统XR手机图文按钮显示不全问题
iOS13.6.1系统XR手机图文按钮显示不全问题
68 0
|
6月前
按钮的image图片是非圆角,直接对UIButton设置圆角,iOS13系统没有圆角效果的问题及解决方案
按钮的image图片是非圆角,直接对UIButton设置圆角,iOS13系统没有圆角效果的问题及解决方案
50 0
|
存储 缓存 iOS开发
iOS 轻量化动态图像下载缓存框架实现
日常开发过程中,图片的下载会占用大量的带宽,图片的加载会消耗大量的性能和内存,正确的使用图片显得尤为重要。 同样也经常需要在各类型控件上读取网络图片和处理本地图片,例如:UIImageView、UIBtton、NSImageView、NSButton等等。
iOS 轻量化动态图像下载缓存框架实现
|
监控 Android开发 iOS开发
Android6.0 源码修改之 仿IOS添加全屏可拖拽浮窗返回按钮
Android6.0 源码修改之 仿IOS添加全屏可拖拽浮窗返回按钮
147 0
|
iOS开发
iOS下载文件保存到手机文件指定目录
iOS下载文件保存到手机文件指定目录
1101 0
|
Web App开发 弹性计算 Android开发
阿里云无影云桌面客户端下载Win/Mac/iOS/安卓/Web端均支持
阿里云无影客户端下载系统Win/Mac/iOS/安卓/Web端均支持
4638 0
阿里云无影云桌面客户端下载Win/Mac/iOS/安卓/Web端均支持
|
Linux iOS开发 开发者
WIN11自定义版本ios镜像下载教程
WIN11自定义版本ios镜像下载教程
WIN11自定义版本ios镜像下载教程