SVIndefiniteAnimatedView.m 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. //
  2. // SVIndefiniteAnimatedView.m
  3. // SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD
  4. //
  5. // Copyright (c) 2014-2019 Guillaume Campagna. All rights reserved.
  6. //
  7. #import "SVIndefiniteAnimatedView.h"
  8. #import "SVProgressHUD.h"
  9. @interface SVIndefiniteAnimatedView ()
  10. @property (nonatomic, strong) CAGradientLayer *indefiniteAnimatedGradientLayer;
  11. @end
  12. @implementation SVIndefiniteAnimatedView
  13. - (void)willMoveToSuperview:(UIView*)newSuperview {
  14. if (newSuperview) {
  15. [self layoutAnimatedLayer];
  16. } else {
  17. [_indefiniteAnimatedGradientLayer removeFromSuperlayer];
  18. _indefiniteAnimatedGradientLayer = nil;
  19. }
  20. }
  21. - (void)layoutAnimatedLayer {
  22. CALayer *layer = self.indefiniteAnimatedGradientLayer;
  23. [self.layer addSublayer:layer];
  24. CGFloat widthDiff = CGRectGetWidth(self.bounds) - CGRectGetWidth(layer.bounds);
  25. CGFloat heightDiff = CGRectGetHeight(self.bounds) - CGRectGetHeight(layer.bounds);
  26. layer.position = CGPointMake(CGRectGetWidth(self.bounds) - CGRectGetWidth(layer.bounds) / 2 - widthDiff / 2, CGRectGetHeight(self.bounds) - CGRectGetHeight(layer.bounds) / 2 - heightDiff / 2);
  27. }
  28. - (CAGradientLayer *)indefiniteAnimatedGradientLayer {
  29. if (!_indefiniteAnimatedGradientLayer) {
  30. CGPoint arcCenter = CGPointMake(self.radius+self.strokeThickness/2+5, self.radius+self.strokeThickness/2+5);
  31. UIBezierPath* smoothedPath = [UIBezierPath bezierPathWithArcCenter:arcCenter radius:self.radius startAngle:(CGFloat) (M_PI*3/2) endAngle:(CGFloat) (-0.5 * M_PI) clockwise:NO];
  32. CAShapeLayer *shapeLayer = [CAShapeLayer layer];
  33. shapeLayer.contentsScale = [[UIScreen mainScreen] scale];
  34. shapeLayer.frame = CGRectMake(0.0f, 0.0f, arcCenter.x*2, arcCenter.y*2);
  35. shapeLayer.fillColor = [UIColor clearColor].CGColor;
  36. shapeLayer.strokeColor = self.strokeColor.CGColor;
  37. shapeLayer.lineWidth = self.strokeThickness;
  38. shapeLayer.lineCap = kCALineCapRound;
  39. shapeLayer.lineJoin = kCALineJoinRound;
  40. shapeLayer.path = smoothedPath.CGPath;
  41. shapeLayer.strokeStart = 0.4f;
  42. shapeLayer.strokeEnd = 1.0f;
  43. _indefiniteAnimatedGradientLayer = [CAGradientLayer layer];
  44. _indefiniteAnimatedGradientLayer.startPoint = CGPointMake(0.5f, 0.0f);
  45. _indefiniteAnimatedGradientLayer.endPoint = CGPointMake(0.5f, 1.0f);
  46. _indefiniteAnimatedGradientLayer.frame = shapeLayer.bounds;
  47. _indefiniteAnimatedGradientLayer.colors = [NSArray arrayWithObjects:
  48. (id)[self.strokeColor colorWithAlphaComponent:0.0f].CGColor,
  49. (id)[self.strokeColor colorWithAlphaComponent:0.5f].CGColor,
  50. (id)self.strokeColor.CGColor,
  51. nil];
  52. _indefiniteAnimatedGradientLayer.locations = [NSArray arrayWithObjects:
  53. @(0.25f),
  54. @(0.5f),
  55. @(1.0f),
  56. nil];
  57. _indefiniteAnimatedGradientLayer.mask = shapeLayer;
  58. NSTimeInterval animationDuration = 1;
  59. CAMediaTimingFunction *linearCurve = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
  60. CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
  61. animation.fromValue = (id) 0;
  62. animation.toValue = @(M_PI*2);
  63. animation.duration = animationDuration;
  64. animation.timingFunction = linearCurve;
  65. animation.removedOnCompletion = NO;
  66. animation.repeatCount = INFINITY;
  67. animation.fillMode = kCAFillModeForwards;
  68. animation.autoreverses = NO;
  69. [_indefiniteAnimatedGradientLayer addAnimation:animation forKey:@"rotate"];
  70. }
  71. return _indefiniteAnimatedGradientLayer;
  72. }
  73. - (void)setFrame:(CGRect)frame {
  74. if (!CGRectEqualToRect(frame, super.frame)) {
  75. [super setFrame:frame];
  76. if (self.superview) {
  77. [self layoutAnimatedLayer];
  78. }
  79. }
  80. }
  81. - (void)setRadius:(CGFloat)radius {
  82. if(radius != _radius) {
  83. _radius = radius;
  84. [_indefiniteAnimatedGradientLayer removeFromSuperlayer];
  85. _indefiniteAnimatedGradientLayer = nil;
  86. if (self.superview) {
  87. [self layoutAnimatedLayer];
  88. }
  89. }
  90. }
  91. - (void)setStrokeColor:(UIColor*)strokeColor {
  92. _strokeColor = strokeColor;
  93. [_indefiniteAnimatedGradientLayer removeFromSuperlayer];
  94. _indefiniteAnimatedGradientLayer = nil;
  95. if (self.superview) {
  96. [self layoutAnimatedLayer];
  97. }
  98. }
  99. - (void)setStrokeThickness:(CGFloat)strokeThickness {
  100. _strokeThickness = strokeThickness;
  101. [_indefiniteAnimatedGradientLayer removeFromSuperlayer];
  102. _indefiniteAnimatedGradientLayer = nil;
  103. if (self.superview) {
  104. [self layoutAnimatedLayer];
  105. }
  106. }
  107. - (CGSize)sizeThatFits:(CGSize)size {
  108. return CGSizeMake((self.radius+self.strokeThickness/2+5)*2, (self.radius+self.strokeThickness/2+5)*2);
  109. }
  110. @end