You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
138 lines
5.1 KiB
138 lines
5.1 KiB
// |
|
// SVIndefiniteAnimatedView.m |
|
// SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD |
|
// |
|
// Copyright (c) 2014-2019 Guillaume Campagna. All rights reserved. |
|
// |
|
|
|
#import "SVIndefiniteAnimatedView.h" |
|
#import "SVProgressHUD.h" |
|
|
|
@interface SVIndefiniteAnimatedView () |
|
|
|
@property (nonatomic, strong) CAGradientLayer *indefiniteAnimatedGradientLayer; |
|
|
|
@end |
|
|
|
@implementation SVIndefiniteAnimatedView |
|
|
|
- (void)willMoveToSuperview:(UIView*)newSuperview { |
|
if (newSuperview) { |
|
[self layoutAnimatedLayer]; |
|
} else { |
|
[_indefiniteAnimatedGradientLayer removeFromSuperlayer]; |
|
_indefiniteAnimatedGradientLayer = nil; |
|
} |
|
} |
|
|
|
- (void)layoutAnimatedLayer { |
|
CALayer *layer = self.indefiniteAnimatedGradientLayer; |
|
[self.layer addSublayer:layer]; |
|
|
|
CGFloat widthDiff = CGRectGetWidth(self.bounds) - CGRectGetWidth(layer.bounds); |
|
CGFloat heightDiff = CGRectGetHeight(self.bounds) - CGRectGetHeight(layer.bounds); |
|
layer.position = CGPointMake(CGRectGetWidth(self.bounds) - CGRectGetWidth(layer.bounds) / 2 - widthDiff / 2, CGRectGetHeight(self.bounds) - CGRectGetHeight(layer.bounds) / 2 - heightDiff / 2); |
|
} |
|
|
|
- (CAGradientLayer *)indefiniteAnimatedGradientLayer { |
|
if (!_indefiniteAnimatedGradientLayer) { |
|
CGPoint arcCenter = CGPointMake(self.radius+self.strokeThickness/2+5, self.radius+self.strokeThickness/2+5); |
|
UIBezierPath* smoothedPath = [UIBezierPath bezierPathWithArcCenter:arcCenter radius:self.radius startAngle:(CGFloat) (M_PI*3/2) endAngle:(CGFloat) (-0.5 * M_PI) clockwise:NO]; |
|
|
|
CAShapeLayer *shapeLayer = [CAShapeLayer layer]; |
|
shapeLayer.contentsScale = [[UIScreen mainScreen] scale]; |
|
shapeLayer.frame = CGRectMake(0.0f, 0.0f, arcCenter.x*2, arcCenter.y*2); |
|
shapeLayer.fillColor = [UIColor clearColor].CGColor; |
|
shapeLayer.strokeColor = self.strokeColor.CGColor; |
|
shapeLayer.lineWidth = self.strokeThickness; |
|
shapeLayer.lineCap = kCALineCapRound; |
|
shapeLayer.lineJoin = kCALineJoinRound; |
|
shapeLayer.path = smoothedPath.CGPath; |
|
shapeLayer.strokeStart = 0.4f; |
|
shapeLayer.strokeEnd = 1.0f; |
|
|
|
_indefiniteAnimatedGradientLayer = [CAGradientLayer layer]; |
|
_indefiniteAnimatedGradientLayer.startPoint = CGPointMake(0.5f, 0.0f); |
|
_indefiniteAnimatedGradientLayer.endPoint = CGPointMake(0.5f, 1.0f); |
|
_indefiniteAnimatedGradientLayer.frame = shapeLayer.bounds; |
|
_indefiniteAnimatedGradientLayer.colors = [NSArray arrayWithObjects: |
|
(id)[self.strokeColor colorWithAlphaComponent:0.0f].CGColor, |
|
(id)[self.strokeColor colorWithAlphaComponent:0.5f].CGColor, |
|
(id)self.strokeColor.CGColor, |
|
nil]; |
|
_indefiniteAnimatedGradientLayer.locations = [NSArray arrayWithObjects: |
|
@(0.25f), |
|
@(0.5f), |
|
@(1.0f), |
|
nil]; |
|
_indefiniteAnimatedGradientLayer.mask = shapeLayer; |
|
|
|
NSTimeInterval animationDuration = 1; |
|
CAMediaTimingFunction *linearCurve = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; |
|
|
|
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"]; |
|
animation.fromValue = (id) 0; |
|
animation.toValue = @(M_PI*2); |
|
animation.duration = animationDuration; |
|
animation.timingFunction = linearCurve; |
|
animation.removedOnCompletion = NO; |
|
animation.repeatCount = INFINITY; |
|
animation.fillMode = kCAFillModeForwards; |
|
animation.autoreverses = NO; |
|
[_indefiniteAnimatedGradientLayer addAnimation:animation forKey:@"rotate"]; |
|
} |
|
return _indefiniteAnimatedGradientLayer; |
|
} |
|
|
|
- (void)setFrame:(CGRect)frame { |
|
|
|
if (!CGRectEqualToRect(frame, super.frame)) { |
|
[super setFrame:frame]; |
|
|
|
if (self.superview) { |
|
[self layoutAnimatedLayer]; |
|
} |
|
} |
|
|
|
} |
|
|
|
- (void)setRadius:(CGFloat)radius { |
|
if(radius != _radius) { |
|
_radius = radius; |
|
|
|
[_indefiniteAnimatedGradientLayer removeFromSuperlayer]; |
|
_indefiniteAnimatedGradientLayer = nil; |
|
|
|
if (self.superview) { |
|
[self layoutAnimatedLayer]; |
|
} |
|
} |
|
} |
|
|
|
- (void)setStrokeColor:(UIColor*)strokeColor { |
|
_strokeColor = strokeColor; |
|
|
|
[_indefiniteAnimatedGradientLayer removeFromSuperlayer]; |
|
_indefiniteAnimatedGradientLayer = nil; |
|
|
|
if (self.superview) { |
|
[self layoutAnimatedLayer]; |
|
} |
|
} |
|
|
|
- (void)setStrokeThickness:(CGFloat)strokeThickness { |
|
_strokeThickness = strokeThickness; |
|
|
|
[_indefiniteAnimatedGradientLayer removeFromSuperlayer]; |
|
_indefiniteAnimatedGradientLayer = nil; |
|
|
|
if (self.superview) { |
|
[self layoutAnimatedLayer]; |
|
} |
|
} |
|
|
|
- (CGSize)sizeThatFits:(CGSize)size { |
|
return CGSizeMake((self.radius+self.strokeThickness/2+5)*2, (self.radius+self.strokeThickness/2+5)*2); |
|
} |
|
|
|
@end
|
|
|