QMUIPieProgressView+RQExtension.m 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. //
  2. // QMUIPieProgressView+RQExtension.m
  3. // jiaPei
  4. //
  5. // Created by 张嵘 on 2022/7/26.
  6. // Copyright © 2022 JCZ. All rights reserved.
  7. //
  8. #import "QMUIPieProgressView+RQExtension.h"
  9. #import "QMUICore.h"
  10. @interface RQUIPieProgressLayer : CALayer
  11. @property(nonatomic, strong) UIColor *fillColor;
  12. @property(nonatomic, strong) UIColor *strokeColor;
  13. @property(nonatomic, assign) float progress;
  14. @property(nonatomic, assign) CFTimeInterval progressAnimationDuration;
  15. @property(nonatomic, assign) BOOL shouldChangeProgressWithAnimation; // default is YES
  16. @property(nonatomic, assign) CGFloat borderInset;
  17. @property(nonatomic, assign) CGFloat lineWidth;
  18. @property(nonatomic, assign) QMUIPieProgressViewShape shape;
  19. @end
  20. @implementation RQUIPieProgressLayer
  21. // 加dynamic才能让自定义的属性支持动画
  22. @dynamic fillColor;
  23. @dynamic strokeColor;
  24. @dynamic progress;
  25. @dynamic shape;
  26. @dynamic lineWidth;
  27. @dynamic borderInset;
  28. - (instancetype)init {
  29. if (self = [super init]) {
  30. self.shouldChangeProgressWithAnimation = YES;
  31. }
  32. return self;
  33. }
  34. + (BOOL)needsDisplayForKey:(NSString *)key {
  35. return [key isEqualToString:@"progress"] || [super needsDisplayForKey:key];
  36. }
  37. - (id<CAAction>)actionForKey:(NSString *)event {
  38. if ([event isEqualToString:@"progress"] && self.shouldChangeProgressWithAnimation) {
  39. CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:event];
  40. animation.fromValue = [self.presentationLayer valueForKey:event];
  41. animation.duration = self.progressAnimationDuration;
  42. return animation;
  43. }
  44. return [super actionForKey:event];
  45. }
  46. - (void)drawInContext:(CGContextRef)context {
  47. if (CGRectIsEmpty(self.bounds)) {
  48. return;
  49. }
  50. CGPoint center = CGPointGetCenterWithRect(self.bounds);
  51. CGFloat radius = MIN(center.x, center.y) - self.borderWidth - self.borderInset;
  52. CGFloat startAngle = -M_PI_2;
  53. CGFloat endAngle = M_PI * 2 * self.progress + startAngle;
  54. switch (self.shape) {
  55. case QMUIPieProgressViewShapeSector: {
  56. // 绘制扇形进度区域
  57. CGContextSetFillColorWithColor(context, self.fillColor.CGColor);
  58. CGContextMoveToPoint(context, center.x, center.y);
  59. CGContextAddArc(context, center.x, center.y, radius, startAngle, endAngle, 0);
  60. CGContextClosePath(context);
  61. CGContextFillPath(context);
  62. }
  63. break;
  64. case QMUIPieProgressViewShapeRing: {
  65. // 绘制环形进度区域
  66. radius -= self.lineWidth;
  67. CGContextSetLineWidth(context, self.lineWidth);
  68. CGContextSetLineCap(context, kCGLineCapRound);
  69. CGContextSetStrokeColorWithColor(context, self.strokeColor.CGColor);
  70. CGContextAddArc(context, center.x, center.y, radius, startAngle, endAngle, 0);
  71. CGContextStrokePath(context);
  72. CGContextClosePath(context);
  73. }
  74. break;
  75. }
  76. [super drawInContext:context];
  77. }
  78. - (void)setFrame:(CGRect)frame {
  79. [super setFrame:frame];
  80. self.cornerRadius = CGRectGetHeight(frame) / 2;
  81. }
  82. @end
  83. @implementation QMUIPieProgressView (RQExtension)
  84. @dynamic rq_borderColor;
  85. + (Class)layerClass {
  86. return [RQUIPieProgressLayer class];
  87. }
  88. - (void)tintColorDidChange {
  89. [super tintColorDidChange];
  90. self.progressLayer.fillColor = self.tintColor;
  91. self.progressLayer.strokeColor = self.tintColor;
  92. // self.progressLayer.borderColor = RGBA_COLOR(239, 145, 167, 0.2).CGColor;
  93. }
  94. - (void)setRq_borderColor:(UIColor *)rq_borderColor {
  95. self.progressLayer.borderColor = rq_borderColor.CGColor;
  96. }
  97. - (RQUIPieProgressLayer *)progressLayer {
  98. return (RQUIPieProgressLayer *)self.layer;
  99. }
  100. @end