经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » iOS » 查看文章
iOS自定义雷达扫描扩散动画
来源:jb51  时间:2021/10/11 9:22:43  对本文有异议

本文实例为大家分享了iOS实现雷达扫描扩散动画的具体代码,供大家参考,具体内容如下

自己自定义了 一个雷达扫描/扩散效果的View。

扫描View 效果如下:

扩散View 效果如下:

自定义的代码如下:

1. RadarView.h

  1. #import <UIKit/UIKit.h>
  2. typedef NS_ENUM(NSInteger, RadarViewType) {
  3. RadarViewTypeScan,
  4. RadarViewTypeDiffuse
  5. };
  6. @interface RadarView : UIView
  7. /** 雷达 空心圆圈的颜色 */
  8. @property (nonatomic, strong) UIColor * radarLineColor;
  9. /** 扇形开始颜色 必须由RGBA值初始化
  10. * [UIColor colorWithRed: green: blue: alpha:]
  11. */
  12. @property (nonatomic, strong) UIColor * startColor;
  13. /** 扇形结束颜色 必须由RGBA值初始化
  14. * [UIColor colorWithRed: green: blue: alpha:]
  15. */
  16. @property (nonatomic, strong) UIColor * endColor;
  17. /**
  18. *
  19. * @param radius 半径
  20. * @param angle 角度
  21. * @param radarLineNum 雷达线数量
  22. * @param hollowRadius 空心圆半径
  23. *
  24. * @return 扫描 雷达 View
  25. */
  26. + (RadarView *)scanRadarViewWithRadius:(CGFloat)radius
  27. angle:(int)angle
  28. radarLineNum:(int)radarLineNum
  29. hollowRadius:(CGFloat)hollowRadius;
  30. /**
  31. *
  32. * @param startRadius 扩散圆 起始的半径
  33. * @param endRadius 扩散圆 消失的半径
  34. * @param circleColor 扩散圆 的颜色
  35. *
  36. * @return 扩散 雷达 View
  37. */
  38. + (RadarView *)diffuseRadarViewWithStartRadius:(CGFloat)startRadius
  39. endRadius:(CGFloat)endRadius
  40. circleColor:(UIColor *)circleColor;
  41. /**
  42. * 展示在targerView上
  43. *
  44. * @param targerView <#targerView description#>
  45. */
  46. - (void)showTargetView:(UIView *)targerView;
  47. - (void)dismiss;
  48. /** 开始扫描动画 */
  49. - (void)startAnimatian;
  50. /** 停止扫描动画 */
  51. - (void)stopAnimation;
  52. @end

2. RadarView.m

  1. #import "RadarView.h"
  2. #define CenterX self.bounds.size.width*0.5
  3. #define CenterY self.bounds.size.height*0.5
  4. #define DefaultRadarLineColor [UIColor colorWithWhite:1 alpha:0.7]
  5. #define DefaultStartColor [UIColor colorWithRed:1 green:1 blue:1 alpha:0.5]
  6. #define DefaultEndColor [UIColor colorWithRed:1 green:1 blue:1 alpha:0]
  7. #define DefaultCircleColor [UIColor colorWithWhite:1 alpha:0.5]
  8. @interface RadarView ()
  9. #pragma mark - 扫描类型的RadarView 属性
  10. /** 扇形半径 */
  11. @property (nonatomic, assign) CGFloat sectorRadius;
  12. /** 扇形 角度 */
  13. @property (nonatomic, assign) int angle;
  14. /** 雷达 空心圆圈的数量 */
  15. @property (nonatomic, assign) int radarLineNum;
  16. /** 中心 空心圆的半径 (一般 这里放置一个圆形的头像) */
  17. @property (nonatomic, assign) int hollowRadius;
  18. #pragma mark - 扩散类型的RadarView 属性
  19. /** 扩散动画 起始 的半径 */
  20. @property (nonatomic, assign) CGFloat startRadius;
  21. /** 扩散动画 结束 的半径 */
  22. @property (nonatomic, assign) CGFloat endRadius;
  23. /** 圆圈的颜色 */
  24. @property (nonatomic, strong) UIColor * circleColor;
  25. @property (nonatomic, strong) NSTimer * timer;
  26. @property (nonatomic, assign) RadarViewType radarViewType;
  27. @end
  28. @implementation RadarView
  29. + (RadarView *)scanRadarViewWithRadius:(CGFloat)radius angle:(int)angle radarLineNum:(int)radarLineNum hollowRadius:(CGFloat)hollowRadius {
  30. return [[self alloc] initWithRadius:radius angle:angle radarLineNum:radarLineNum hollowRadius:hollowRadius];
  31. }
  32. - (instancetype)initWithRadius:(CGFloat)radius
  33. angle:(int)angle
  34. radarLineNum:(int)radarLineNum
  35. hollowRadius:(CGFloat)hollowRadius {
  36. if (self = [super init]) {
  37. self.radarViewType = RadarViewTypeScan;
  38. self.sectorRadius = radius;
  39. self.frame = CGRectMake(0, 0, radius*2, radius*2);
  40. self.angle = angle;
  41. self.radarLineNum = radarLineNum-1;
  42. self.hollowRadius = hollowRadius;
  43. self.backgroundColor = [UIColor clearColor];
  44. }
  45. return self;
  46. }
  47. + (RadarView *)diffuseRadarViewWithStartRadius:(CGFloat)startRadius endRadius:(CGFloat)endRadius circleColor:(UIColor *)circleColor {
  48. return [[self alloc] initWithStartRadius:startRadius endRadius:endRadius circleColor:circleColor];
  49. }
  50. - (instancetype)initWithStartRadius:(CGFloat)startRadius endRadius:(CGFloat)endRadius circleColor:(UIColor *)circleColor {
  51. if (self = [super init]) {
  52. self.radarViewType = RadarViewTypeDiffuse;
  53. self.frame = CGRectMake(0, 0, endRadius*2, endRadius*2);
  54. self.startRadius = startRadius;
  55. self.endRadius = endRadius;
  56. self.circleColor = circleColor;
  57. self.backgroundColor = [UIColor clearColor];
  58. }
  59. return self;
  60. }
  61. // Only override drawRect: if you perform custom drawing.
  62. // An empty implementation adversely affects performance during animation.
  63. - (void)drawRect:(CGRect)rect {
  64. // Drawing code
  65. if (_radarViewType == RadarViewTypeScan) {
  66. if (!_startColor) {
  67. _startColor = DefaultStartColor;
  68. }
  69. if (!_endColor) {
  70. _endColor = DefaultEndColor;
  71. }
  72. if (!_radarLineColor) {
  73. _radarLineColor = DefaultRadarLineColor;
  74. }
  75. // 画雷达线
  76. [self drawRadarLine];
  77. CGContextRef context = UIGraphicsGetCurrentContext();
  78. // 把要画的扇形 分开画,一次画1°,每次的颜色渐变
  79. for (int i = 0; i < _angle; i++) {
  80. UIColor * color = [self colorWithCurrentAngleProportion:i*1.0/_angle];
  81. [self drawSectorWithContext:context color:color startAngle:-90-i];
  82. }
  83. }
  84. }
  85. /** 画扇形 */
  86. - (void)drawSectorWithContext:(CGContextRef)context
  87. color:(UIColor *)color
  88. startAngle:(CGFloat)startAngle {
  89. //画扇形,也就画圆,只不过是设置角度的大小,形成一个扇形
  90. CGContextSetFillColorWithColor(context, color.CGColor);//填充颜色
  91. CGContextSetLineWidth(context, 0);//线的宽度
  92. //以self.radius为半径围绕圆心画指定角度扇形
  93. CGContextMoveToPoint(context, CenterX, CenterY);
  94. CGContextAddArc(context, CenterX, CenterY, _sectorRadius, startAngle * M_PI / 180, (startAngle-1) * M_PI / 180, 1);
  95. CGContextClosePath(context);
  96. CGContextDrawPath(context, kCGPathFillStroke); //绘制路径
  97. }
  98. /** 画雷达线 */
  99. - (void)drawRadarLine {
  100. CGFloat minRadius = (_sectorRadius-_hollowRadius)*(pow(0.618, _radarLineNum-1));
  101. /** 画 围着空心半径的第一个空心圆,此圆不在计数内 */
  102. [self drawLineWithRadius:_hollowRadius+minRadius*0.382];
  103. for (int i = 0; i < _radarLineNum; i++) {
  104. [self drawLineWithRadius:_hollowRadius + minRadius/pow(0.618, i)];
  105. }
  106. }
  107. /** 画空心圆 */
  108. - (void)drawLineWithRadius:(CGFloat)radius {
  109. CAShapeLayer *solidLine = [CAShapeLayer layer];
  110. CGMutablePathRef solidPath = CGPathCreateMutable();
  111. solidLine.lineWidth = 1.0f ;
  112. solidLine.strokeColor = _radarLineColor.CGColor;
  113. solidLine.fillColor = [UIColor clearColor].CGColor;
  114. CGPathAddEllipseInRect(solidPath, nil, CGRectMake(self.bounds.size.width*0.5-radius, self.bounds.size.height*0.5-radius, radius*2, radius*2));
  115. solidLine.path = solidPath;
  116. CGPathRelease(solidPath);
  117. [self.layer addSublayer:solidLine];
  118. }
  119. #pragma mark - 展示
  120. - (void)showTargetView:(UIView *)targerView {
  121. self.center = targerView.center;
  122. [targerView addSubview:self];
  123. }
  124. #pragma mark -
  125. - (void)dismiss {
  126. [self removeFromSuperview];
  127. }
  128. #pragma mark - 开始动画
  129. - (void)startAnimatian {
  130. if (_radarViewType == RadarViewTypeScan) {
  131. CABasicAnimation* rotationAnimation;
  132. rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
  133. rotationAnimation.toValue = [NSNumber numberWithFloat: 1 * M_PI * 2.0 ];
  134. rotationAnimation.duration = 2;
  135. rotationAnimation.cumulative = YES;
  136. rotationAnimation.repeatCount = INT_MAX;
  137. [self.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"];
  138. } else {
  139. [self diffuseAnimation];
  140. _timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(diffuseAnimation) userInfo:nil repeats:YES];
  141. }
  142. }
  143. #pragma mark - 结束动画
  144. - (void)stopAnimation {
  145. if (_radarViewType == RadarViewTypeScan) {
  146. [self.layer removeAnimationForKey:@"rotationAnimation"];
  147. } else {
  148. [_timer invalidate];
  149. _timer = nil;
  150. }
  151. }
  152. - (UIColor *)colorWithCurrentAngleProportion:(CGFloat)angleProportion {
  153. NSArray * startRGBA = [self RGBA_WithColor:_startColor];
  154. NSArray * endRGBA = [self RGBA_WithColor:_endColor];
  155. CGFloat currentR = [startRGBA[0] floatValue] - ([startRGBA[0] floatValue]-[endRGBA[0] floatValue]) * angleProportion;
  156. CGFloat currentG = [startRGBA[1] floatValue] - ([startRGBA[1] floatValue]-[endRGBA[1] floatValue]) * angleProportion;
  157. CGFloat currentB = [startRGBA[2] floatValue] - ([startRGBA[2] floatValue]-[endRGBA[2] floatValue]) * angleProportion;
  158. CGFloat currentA = [startRGBA[3] floatValue] - ([startRGBA[3] floatValue]-[endRGBA[3] floatValue]) * angleProportion;
  159. return [UIColor colorWithRed:currentR green:currentG blue:currentB alpha:currentA];
  160. }
  161. /**
  162. * 将UIColor对象解析成RGBA 值 的数组
  163. *
  164. * @param color UIColor对象,有RGBA值 初始化的
  165. *[UIColor colorWithRed:rValue green:gValue blue:bValue alpha:aValue]
  166. *
  167. * @return 包含RGBA值得数组[rValue, gValue, bValue, aValue]
  168. */
  169. - (NSArray *)RGBA_WithColor:(UIColor *)color {
  170. NSString * colorStr = [NSString stringWithFormat:@"%@", color];
  171. //将RGB值描述分隔成字符串
  172. NSArray * colorValueArray = [colorStr componentsSeparatedByString:@" "];
  173. NSString * R = colorValueArray[1];
  174. NSString * G = colorValueArray[2];
  175. NSString * B = colorValueArray[3];
  176. NSString * A = colorValueArray[4];
  177. return @[R, G, B, A];
  178. }
  179. /** 画圆 */
  180. - (UIImage *)drawCircle {
  181. UIGraphicsBeginImageContext(CGSizeMake(_endRadius*2, _endRadius*2));
  182. CGContextRef context = UIGraphicsGetCurrentContext();
  183. CGContextMoveToPoint(context, CenterX, CenterY);
  184. CGContextSetFillColorWithColor(context, _circleColor.CGColor);
  185. CGContextAddArc(context, CenterX, CenterY, _endRadius, 0, -2*M_PI, 1);
  186. CGContextFillPath(context);
  187. UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
  188. UIGraphicsEndImageContext();
  189. return img;
  190. }
  191. - (void)diffuseAnimation {
  192. UIImageView * imgView = [[UIImageView alloc] init];
  193. imgView.image = [self drawCircle];
  194. imgView.frame = CGRectMake(0, 0, _startRadius, _startRadius);
  195. imgView.center = CGPointMake(CenterX, CenterY);
  196. [self addSubview:imgView];
  197. [UIView animateWithDuration:2 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
  198. imgView.frame = CGRectMake(0, 0, _endRadius*2, _endRadius*2);
  199. imgView.center = CGPointMake(CenterX, CenterY);
  200. imgView.alpha = 0;
  201. } completion:^(BOOL finished) {
  202. [imgView removeFromSuperview];
  203. }];
  204. }
  205. @end

3. ViewController.m 中使用的代码:

  1. #import "ViewController.h"
  2. #import "RadarView.h"
  3. @interface ViewController ()
  4. @property (nonatomic, strong) RadarView * scanRadarView;
  5. @property (nonatomic, strong) RadarView * diffuseRadarView;
  6. @end
  7. @implementation ViewController
  8. - (void)viewDidLoad {
  9. [super viewDidLoad];
  10. /** 扫描 类型 RadarView */
  11. // _scanRadarView = [RadarView scanRadarViewWithRadius:self.view.bounds.size.width*0.5 angle:400 radarLineNum:5 hollowRadius:0];
  12. /** 扩散 类型 RadarView */
  13. _diffuseRadarView = [RadarView diffuseRadarViewWithStartRadius:7 endRadius:self.view.bounds.size.width*0.5 circleColor:[UIColor whiteColor]];
  14. }
  15. - (void)viewDidAppear:(BOOL)animated {
  16. [super viewDidAppear:animated];
  17. // [_scanRadarView showTargetView:self.view];
  18. // [_scanRadarView startAnimatian];
  19. [_diffuseRadarView showTargetView:self.view];
  20. [_diffuseRadarView startAnimatian];
  21. }
  22. - (void)didReceiveMemoryWarning {
  23. [super didReceiveMemoryWarning];
  24. // Dispose of any resources that can be recreated.
  25. }
  26. @end

现在定义的是能代码加载使用,等有空了,再封装一些方法能在Storyboard中直接使用。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持w3xue。

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号