分享

iOS 进度条、加载、安装动画

 wintelsui 2020-04-17

首先看一下效果图:


下面贴上代码:

控制器ViewController:

  1. #import <UIKit/UIKit.h>
  2. @interface ViewController : UIViewController
  3. @end
  4. /*** ---------------分割线--------------- ***/
  5. #import "ViewController.h"
  6. #import "HWWaveView.h"
  7. #import "HWCircleView.h"
  8. #import "HWProgressView.h"
  9. #import "HWInstallView.h"
  10. @interface ViewController ()
  11. @property (nonatomic, strong) NSTimer *timer;
  12. @property (nonatomic, weak) HWWaveView *waveView;
  13. @property (nonatomic, weak) HWCircleView *circleView;
  14. @property (nonatomic, weak) HWProgressView *progressView;
  15. @property (nonatomic, weak) HWInstallView *installView;
  16. @end
  17. @implementation ViewController
  18. - (void)viewDidLoad {
  19. [super viewDidLoad];
  20. //创建控件
  21. [self creatControl];
  22. //添加定时器
  23. [self addTimer];
  24. }
  25. - (void)creatControl
  26. {
  27. //波浪
  28. HWWaveView *waveView = [[HWWaveView alloc] initWithFrame:CGRectMake(30, 100, 150, 150)];
  29. [self.view addSubview:waveView];
  30. self.waveView = waveView;
  31. //圆圈
  32. HWCircleView *circleView = [[HWCircleView alloc] initWithFrame:CGRectMake(220, 100, 150, 150)];
  33. [self.view addSubview:circleView];
  34. self.circleView = circleView;
  35. //进度条
  36. HWProgressView *progressView = [[HWProgressView alloc] initWithFrame:CGRectMake(30, 365, 150, 20)];
  37. [self.view addSubview:progressView];
  38. self.progressView = progressView;
  39. //加载安装效果
  40. HWInstallView *installView = [[HWInstallView alloc] initWithFrame:CGRectMake(220, 300, 150, 150)];
  41. [self.view addSubview:installView];
  42. self.installView = installView;
  43. }
  44. - (void)addTimer
  45. {
  46. _timer = [NSTimer scheduledTimerWithTimeInterval:0.2f target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
  47. [[NSRunLoop mainRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
  48. }
  49. - (void)timerAction
  50. {
  51. _waveView.progress += 0.01;
  52. _circleView.progress += 0.01;
  53. _progressView.progress += 0.01;
  54. _installView.progress += 0.01;
  55. if (_waveView.progress >= 1) {
  56. [self removeTimer];
  57. NSLog(@"完成");
  58. }
  59. }
  60. - (void)removeTimer
  61. {
  62. [_timer invalidate];
  63. _timer = nil;
  64. }
  65. @end

波浪HWWaveView:

  1. #import <UIKit/UIKit.h>
  2. @interface HWWaveView : UIView
  3. @property (nonatomic, assign) CGFloat progress;
  4. @end
  5. /*** ---------------分割线--------------- ***/
  6. #import "HWWaveView.h"
  7. #define KHWWaveFillColor [UIColor groupTableViewBackgroundColor] //填充颜色
  8. #define KHWWaveTopColor [UIColor colorWithRed:0/255.0 green:191/255.0 blue:255/255.0 alpha:1.0f] //前面波浪颜色
  9. #define KHWWaveBottomColor [UIColor colorWithRed:0/255.0 green:191/255.0 blue:255/255.0 alpha:0.4f] //后面波浪颜色
  10. @interface HWWaveView ()
  11. @property (nonatomic, strong) CADisplayLink *displayLink;
  12. @property (nonatomic, assign) CGFloat wave_amplitude;//振幅a(y = asin(wx+φ) + k)
  13. @property (nonatomic, assign) CGFloat wave_cycle;//周期w
  14. @property (nonatomic, assign) CGFloat wave_h_distance;//两个波水平之间偏移
  15. @property (nonatomic, assign) CGFloat wave_v_distance;//两个波竖直之间偏移
  16. @property (nonatomic, assign) CGFloat wave_scale;//水波速率
  17. @property (nonatomic, assign) CGFloat wave_offsety;//波峰所在位置的y坐标
  18. @property (nonatomic, assign) CGFloat wave_move_width;//移动的距离,配合速率设置
  19. @property (nonatomic, assign) CGFloat wave_offsetx;//偏移
  20. @property (nonatomic, assign) CGFloat offsety_scale;//上升的速度
  21. @end
  22. @implementation HWWaveView
  23. - (instancetype)initWithFrame:(CGRect)frame
  24. {
  25. if (self = [super initWithFrame:frame]) {
  26. self.backgroundColor = [UIColor clearColor];
  27. //初始化信息
  28. [self initInfo];
  29. }
  30. return self;
  31. }
  32. - (void)initInfo
  33. {
  34. //进度
  35. _progress = 0;
  36. //振幅
  37. _wave_amplitude = self.frame.size.height / 25;
  38. //周期
  39. _wave_cycle = 2 * M_PI / (self.frame.size.width * 0.9);
  40. //两个波水平之间偏移
  41. _wave_h_distance = 2 * M_PI / _wave_cycle * 0.6;
  42. //两个波竖直之间偏移
  43. _wave_v_distance = _wave_amplitude * 0.4;
  44. //移动的距离,配合速率设置
  45. _wave_move_width = 0.5;
  46. //水波速率
  47. _wave_scale = 0.4;
  48. //上升的速度
  49. _offsety_scale = 0.1;
  50. //波峰所在位置的y坐标,刚开始的时候_wave_offsety是最大值
  51. _wave_offsety = (1 - _progress) * (self.frame.size.height + 2 * _wave_amplitude);
  52. [self addDisplayLinkAction];
  53. }
  54. - (void)addDisplayLinkAction
  55. {
  56. _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkAction)];
  57. [_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
  58. }
  59. - (void)displayLinkAction
  60. {
  61. _wave_offsetx += _wave_move_width * _wave_scale;
  62. //完成
  63. if (_wave_offsety <= 0.01) [self removeDisplayLinkAction];
  64. [self setNeedsDisplay];
  65. }
  66. - (void)removeDisplayLinkAction
  67. {
  68. [_displayLink invalidate];
  69. _displayLink = nil;
  70. }
  71. - (void)drawRect:(CGRect)rect
  72. {
  73. UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:rect];
  74. [KHWWaveFillColor setFill];
  75. [path fill];
  76. [path addClip];
  77. //绘制两个波形图
  78. [self drawWaveColor:KHWWaveTopColor offsetx:0 offsety:0];
  79. [self drawWaveColor:KHWWaveBottomColor offsetx:_wave_h_distance offsety:_wave_v_distance];
  80. }
  81. - (void)drawWaveColor:(UIColor *)color offsetx:(CGFloat)offsetx offsety:(CGFloat)offsety
  82. {
  83. //波浪动画,进度的实际操作范围是,多加上两个振幅的高度,到达设置进度的位置y
  84. CGFloat end_offY = (1 - _progress) * (self.frame.size.height + 2 * _wave_amplitude);
  85. if (_wave_offsety != end_offY) {
  86. if (end_offY < _wave_offsety) {
  87. _wave_offsety = MAX(_wave_offsety -= (_wave_offsety - end_offY) * _offsety_scale, end_offY);
  88. }else {
  89. _wave_offsety = MIN(_wave_offsety += (end_offY - _wave_offsety) * _offsety_scale, end_offY);
  90. }
  91. }
  92. UIBezierPath *wavePath = [UIBezierPath bezierPath];
  93. for (float next_x = 0.f; next_x <= self.frame.size.width; next_x ++) {
  94. //正弦函数,绘制波形
  95. CGFloat next_y = _wave_amplitude * sin(_wave_cycle * next_x + _wave_offsetx + offsetx / self.bounds.size.width * 2 * M_PI) + _wave_offsety + offsety;
  96. if (next_x == 0) {
  97. [wavePath moveToPoint:CGPointMake(next_x, next_y - _wave_amplitude)];
  98. }else {
  99. [wavePath addLineToPoint:CGPointMake(next_x, next_y - _wave_amplitude)];
  100. }
  101. }
  102. [wavePath addLineToPoint:CGPointMake(self.frame.size.width, self.frame.size.height)];
  103. [wavePath addLineToPoint:CGPointMake(0, self.bounds.size.height)];
  104. [color set];
  105. [wavePath fill];
  106. }
  107. @end

圆圈HWCircleView:

  1. #import <UIKit/UIKit.h>
  2. @interface HWCircleView : UIView
  3. @property (nonatomic, assign) CGFloat progress;
  4. @end
  5. /*** ---------------分割线--------------- ***/
  6. #import "HWCircleView.h"
  7. #define KHWCircleLineWidth 10.0f
  8. #define KHWCircleFont [UIFont boldSystemFontOfSize:26.0f]
  9. #define KHWCircleColor [UIColor colorWithRed:0/255.0 green:191/255.0 blue:255/255.0 alpha:1]
  10. @interface HWCircleView ()
  11. @property (nonatomic, weak) UILabel *cLabel;
  12. @end
  13. @implementation HWCircleView
  14. - (instancetype)initWithFrame:(CGRect)frame
  15. {
  16. if (self = [super initWithFrame:frame]) {
  17. self.backgroundColor = [UIColor clearColor];
  18. //百分比标签
  19. UILabel *cLabel = [[UILabel alloc] initWithFrame:self.bounds];
  20. cLabel.font = KHWCircleFont;
  21. cLabel.textColor = KHWCircleColor;
  22. cLabel.textAlignment = NSTextAlignmentCenter;
  23. [self addSubview:cLabel];
  24. self.cLabel = cLabel;
  25. }
  26. return self;
  27. }
  28. - (void)setProgress:(CGFloat)progress
  29. {
  30. _progress = progress;
  31. _cLabel.text = [NSString stringWithFormat:@"%d%%", (int)floor(progress * 100)];
  32. [self setNeedsDisplay];
  33. }
  34. - (void)drawRect:(CGRect)rect
  35. {
  36. //路径
  37. UIBezierPath *path = [[UIBezierPath alloc] init];
  38. //线宽
  39. path.lineWidth = KHWCircleLineWidth;
  40. //颜色
  41. [KHWCircleColor set];
  42. //拐角
  43. path.lineCapStyle = kCGLineCapRound;
  44. path.lineJoinStyle = kCGLineJoinRound;
  45. //半径
  46. CGFloat radius = (MIN(rect.size.width, rect.size.height) - KHWCircleLineWidth) * 0.5;
  47. //画弧(参数:中心、半径、起始角度(3点钟方向为0)、结束角度、是否顺时针)
  48. [path addArcWithCenter:(CGPoint){rect.size.width * 0.5, rect.size.height * 0.5} radius:radius startAngle:M_PI * 1.5 endAngle:M_PI * 1.5 + M_PI * 2 * _progress clockwise:YES];
  49. //连线
  50. [path stroke];
  51. }
  52. @end

进度条HWProgressView:

  1. #import <UIKit/UIKit.h>
  2. @interface HWProgressView : UIView
  3. @property (nonatomic, assign) CGFloat progress;
  4. @end
  5. /*** ---------------分割线--------------- ***/
  6. #import "HWProgressView.h"
  7. #define KProgressBorderWidth 2.0f
  8. #define KProgressPadding 1.0f
  9. #define KProgressColor [UIColor colorWithRed:0/255.0 green:191/255.0 blue:255/255.0 alpha:1]
  10. @interface HWProgressView ()
  11. @property (nonatomic, weak) UIView *tView;
  12. @end
  13. @implementation HWProgressView
  14. - (instancetype)initWithFrame:(CGRect)frame
  15. {
  16. if (self = [super initWithFrame:frame]) {
  17. //边框
  18. UIView *borderView = [[UIView alloc] initWithFrame:self.bounds];
  19. borderView.layer.cornerRadius = self.bounds.size.height * 0.5;
  20. borderView.layer.masksToBounds = YES;
  21. borderView.backgroundColor = [UIColor whiteColor];
  22. borderView.layer.borderColor = [KProgressColor CGColor];
  23. borderView.layer.borderWidth = KProgressBorderWidth;
  24. [self addSubview:borderView];
  25. //进度
  26. UIView *tView = [[UIView alloc] init];
  27. tView.backgroundColor = KProgressColor;
  28. tView.layer.cornerRadius = (self.bounds.size.height - (KProgressBorderWidth + KProgressPadding) * 2) * 0.5;
  29. tView.layer.masksToBounds = YES;
  30. [self addSubview:tView];
  31. self.tView = tView;
  32. }
  33. return self;
  34. }
  35. - (void)setProgress:(CGFloat)progress
  36. {
  37. _progress = progress;
  38. CGFloat margin = KProgressBorderWidth + KProgressPadding;
  39. CGFloat maxWidth = self.bounds.size.width - margin * 2;
  40. CGFloat heigth = self.bounds.size.height - margin * 2;
  41. _tView.frame = CGRectMake(margin, margin, maxWidth * progress, heigth);
  42. }
  43. @end

加载安装效果HWInstallView:

  1. #import <UIKit/UIKit.h>
  2. @interface HWInstallView : UIView
  3. @property (nonatomic, assign) CGFloat progress;
  4. @end
  5. /*** ---------------分割线--------------- ***/
  6. #import "HWInstallView.h"
  7. #define KHWInstallViewMargin 10
  8. #define KHWInstallColor [UIColor colorWithRed:0/255.0 green:191/255.0 blue:255/255.0 alpha:1]
  9. @implementation HWInstallView
  10. - (instancetype)initWithFrame:(CGRect)frame
  11. {
  12. if (self = [super initWithFrame:frame]) {
  13. self.backgroundColor = [UIColor clearColor];
  14. }
  15. return self;
  16. }
  17. - (void)setProgress:(CGFloat)progress
  18. {
  19. _progress = progress;
  20. [self setNeedsDisplay];
  21. }
  22. - (void)drawRect:(CGRect)rect
  23. {
  24. CGContextRef context = UIGraphicsGetCurrentContext();
  25. CGFloat xCenter = rect.size.width * 0.5;
  26. CGFloat yCenter = rect.size.height * 0.5;
  27. CGFloat radius = MIN(rect.size.width, rect.size.height) * 0.5 - KHWInstallViewMargin;
  28. //背景遮罩
  29. [KHWInstallColor set];
  30. CGFloat lineW = MAX(rect.size.width, rect.size.height) * 0.5;
  31. CGContextSetLineWidth(context, lineW);
  32. CGContextAddArc(context, xCenter, yCenter, radius + lineW * 0.5 + 5, 0, M_PI * 2, 1);
  33. CGContextStrokePath(context);
  34. //进程圆
  35. CGContextSetLineWidth(context, 1);
  36. CGContextMoveToPoint(context, xCenter, yCenter);
  37. CGContextAddLineToPoint(context, xCenter, 0);
  38. CGFloat endAngle = - M_PI * 0.5 + _progress * M_PI * 2 + 0.001;
  39. CGContextAddArc(context, xCenter, yCenter, radius, - M_PI * 0.5, endAngle, 1);
  40. CGContextFillPath(context);
  41. }
  42. @end

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多