使用Facebook开源代码FBShimmering封装进度显示的ShimmeCircleView
效果图:
静态图:
源码:
ShimmeCircleView.h 与 ShimmeCircleView.m
// // ShimmeCircleView.h // YouXianMingClock // // Created by YouXianMing on 14-10-13. // Copyright (c) 2014年 YouXianMing. All rights reserved. // #import <UIKit/UIKit.h> @interface ShimmeCircleView : UIView /** * 时候开启闪光效果,默认是 NO */ @property (nonatomic, assign) BOOL shimmering; /** * 当 shimmering 开启时,进入到闪光状态中的动画时间,默认值是 0.3. */ @property (nonatomic, assign) CFTimeInterval shimmeringBeginFadeDuration; /** * 当 shimmering 结束时,从闪光动画退出到正常的时间,默认值是 0.3. */ @property (nonatomic, assign) CFTimeInterval shimmeringEndFadeDuration; /** * The opacity of the content before it is shimmering. Defaults to 0.3. */ @property (nonatomic, assign) CGFloat shimmeringOpacity; /** * The time interval between shimmerings in seconds. Defaults to 0.6. */ @property (nonatomic, assign) CFTimeInterval shimmeringPauseDuration; /** * 圆的颜色,默认为红色 */ @property (nonatomic, assign) UIColor *shapeColor; /** * 圆的线宽度,默认为1 */ @property (nonatomic, assign) CGFloat shapeLineWidth; /** * 动画时间间隔 */ @property (nonatomic, assign) CFTimeInterval strokeAnimationDuration; /** * 更新shapeLayer(修改后必须更新path才能够生效) */ - (void)updateShapeLayer; - (void)doPOPBasicEndAnimationToValue:(CGFloat)value; - (void)doPOPBasicStartAnimationToValue:(CGFloat)value; @end
// // ShimmeCircleView.m // YouXianMingClock // // Created by YouXianMing on 14-10-13. // Copyright (c) 2014年 YouXianMing. All rights reserved. // #import "ShimmeCircleView.h" #import "FBShimmering.h" #import "FBShimmeringLayer.h" #import "FBShimmeringView.h" #import "POP.h" /** * 将角度转换为弧度 * * @param d 角度 * * @return 弧度 */ #define DEGREES__TO__RADIANS(d) ((d) * M_PI / 180.f) @interface ShimmeCircleView () { CAShapeLayer *_shapeLayer; // 形状的layer FBShimmeringLayer *_showLayer; // 辉光的layer } @end @implementation ShimmeCircleView - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { // 创建FBShimmeringLayer if (_showLayer == nil) { _showLayer = [FBShimmeringLayer new]; _showLayer.frame = self.bounds; _showLayer.position = self.center; _showLayer.shimmering = NO; // 默认设置关闭 _showLayer.shimmeringBeginFadeDuration = 0.3; // 开始进入闪光时候的时间 _showLayer.shimmeringEndFadeDuration = 0.3; // 从闪光进入没有闪光时候的时间 _showLayer.shimmeringOpacity = 0.3; _showLayer.shimmeringPauseDuration = 0.6f; [self.layer addSublayer:_showLayer]; } // 制造形状的layer if (_shapeLayer == nil) { _shapeLayer = [CAShapeLayer layer]; _shapeLayer.lineWidth = 1.f; _shapeLayer.strokeEnd = 0.f; _shapeLayer.strokeColor = [UIColor redColor].CGColor; _shapeLayer.fillColor = [UIColor clearColor].CGColor; // 设置填充颜色为透明 _shapeLayer.path = [self createCirclePath].CGPath; _showLayer.contentLayer = _shapeLayer; } } return self; } - (void)updateShapeLayer { if (_shapeColor) { _shapeLayer.strokeColor = _shapeColor.CGColor; } if (_shapeLineWidth > 0) { _shapeLayer.lineWidth = _shapeLineWidth; _shapeLayer.path = [self createCirclePath].CGPath; // 更新path } } - (void)doPOPBasicEndAnimationToValue:(CGFloat)value { [self doStrokeEndAnimationFromValue:_shapeLayer.strokeEnd toValue:value shapeLayer:_shapeLayer duration:(_strokeAnimationDuration > 0 ? _strokeAnimationDuration : 0.4f) timingFunctionName:nil]; } - (void)doPOPBasicStartAnimationToValue:(CGFloat)value { [self doStrokeStartAnimationFromValue:_shapeLayer.strokeStart toValue:value shapeLayer:_shapeLayer duration:(_strokeAnimationDuration > 0 ? _strokeAnimationDuration : 0.4f) timingFunctionName:nil]; } /** * 根据frame值创建圆形的贝塞尔曲线 * * @return 圆形的贝塞尔曲线 */ - (UIBezierPath *)createCirclePath { UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.bounds.size.height / 2.f, self.bounds.size.width / 2.f) radius:self.bounds.size.height / 2.f - _shapeLayer.lineWidth / 2.f startAngle:DEGREES__TO__RADIANS(-90) endAngle:DEGREES__TO__RADIANS(270) clockwise:YES]; return path; } #pragma mark - 重写各种setter方法 /** * 重写shimmering的setter,getter方法 */ @synthesize shimmering = _shimmering; - (BOOL)shimmering { return _shimmering; } - (void)setShimmering:(BOOL)shimmering { _shimmering = shimmering; _showLayer.shimmering = shimmering; } /** * 重写shimmeringBeginFadeDuration的setter,getter方法 */ @synthesize shimmeringBeginFadeDuration = _shimmeringBeginFadeDuration; - (CFTimeInterval)shimmeringBeginFadeDuration { return _shimmeringBeginFadeDuration; } - (void)setShimmeringBeginFadeDuration:(CFTimeInterval)shimmeringBeginFadeDuration { _shimmeringBeginFadeDuration = shimmeringBeginFadeDuration; _showLayer.shimmeringBeginFadeDuration = shimmeringBeginFadeDuration; } /** * 重写shimmeringEndFadeDuration的setter,getter方法 */ @synthesize shimmeringEndFadeDuration = _shimmeringEndFadeDuration; - (CFTimeInterval)shimmeringEndFadeDuration { return _shimmeringEndFadeDuration; } - (void)setShimmeringEndFadeDuration:(CFTimeInterval)shimmeringEndFadeDuration { _shimmeringEndFadeDuration = shimmeringEndFadeDuration; _showLayer.shimmeringEndFadeDuration = shimmeringEndFadeDuration; } /** * 重写shimmeringOpacity的setter,getter方法 */ @synthesize shimmeringOpacity = _shimmeringOpacity; - (CGFloat)shimmeringOpacity { return _shimmeringOpacity; } - (void)setShimmeringOpacity:(CGFloat)shimmeringOpacity { _shimmeringOpacity = shimmeringOpacity; _showLayer.shimmeringOpacity = shimmeringOpacity; } /** * 重写shimmeringPauseDuration的setter,getter方法 */ @synthesize shimmeringPauseDuration = _shimmeringPauseDuration; - (CFTimeInterval)shimmeringPauseDuration { return _shimmeringPauseDuration; } - (void)setShimmeringPauseDuration:(CFTimeInterval)shimmeringPauseDuration { _shimmeringPauseDuration = shimmeringPauseDuration; _showLayer.shimmeringPauseDuration = shimmeringPauseDuration; } #pragma mark - 私有方法 /** * StrokeEnd动画 * * @param fromValue 初始值 * @param toValue 结束值 * @param layer 被动画的CAShapeLayer * @param duration 动画时间 * @param name 动画时间类型,可以选择的类型如下:kCAMediaTimingFunctionLinear kCAMediaTimingFunctionEaseIn kCAMediaTimingFunctionEaseOut kCAMediaTimingFunctionEaseInEaseOut kCAMediaTimingFunctionDefault */ - (void)doStrokeEndAnimationFromValue:(CGFloat)fromValue toValue:(CGFloat)toValue shapeLayer:(CAShapeLayer *)layer duration:(CFTimeInterval)duration timingFunctionName:(NSString *)name { POPBasicAnimation *pathAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPShapeLayerStrokeEnd]; pathAnimation.duration = duration; if (name) { pathAnimation.timingFunction = [CAMediaTimingFunction functionWithName:name]; } pathAnimation.fromValue = [NSNumber numberWithFloat:fromValue]; pathAnimation.toValue = [NSNumber numberWithFloat:toValue]; [layer pop_addAnimation:pathAnimation forKey:nil]; } /** * StrokeStart动画 * * @param fromValue 初始值 * @param toValue 结束值 * @param layer 被动画的CAShapeLayer * @param duration 动画时间 * @param name 动画时间类型,可以选择的类型如下:kCAMediaTimingFunctionLinear kCAMediaTimingFunctionEaseIn kCAMediaTimingFunctionEaseOut kCAMediaTimingFunctionEaseInEaseOut kCAMediaTimingFunctionDefault */ - (void)doStrokeStartAnimationFromValue:(CGFloat)fromValue toValue:(CGFloat)toValue shapeLayer:(CAShapeLayer *)layer duration:(CFTimeInterval)duration timingFunctionName:(NSString *)name { POPBasicAnimation *pathAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPShapeLayerStrokeStart]; pathAnimation.duration = duration; if (name) { pathAnimation.timingFunction = [CAMediaTimingFunction functionWithName:name]; } pathAnimation.fromValue = [NSNumber numberWithFloat:fromValue]; pathAnimation.toValue = [NSNumber numberWithFloat:toValue]; [layer pop_addAnimation:pathAnimation forKey:nil]; } @end
以下是需要注意的地方:
以下是使用细节: