本文实例为大家分享了iOS实现雷达扫描扩散动画的具体代码,供大家参考,具体内容如下
自己自定义了 一个雷达扫描/扩散效果的View。
扫描View 效果如下:

扩散View 效果如下:

自定义的代码如下:
1. RadarView.h
- #import <UIKit/UIKit.h>
-
- typedef NS_ENUM(NSInteger, RadarViewType) {
- RadarViewTypeScan,
- RadarViewTypeDiffuse
- };
-
- @interface RadarView : UIView
-
- /** 雷达 空心圆圈的颜色 */
- @property (nonatomic, strong) UIColor * radarLineColor;
- /** 扇形开始颜色 必须由RGBA值初始化
- * [UIColor colorWithRed: green: blue: alpha:]
- */
- @property (nonatomic, strong) UIColor * startColor;
- /** 扇形结束颜色 必须由RGBA值初始化
- * [UIColor colorWithRed: green: blue: alpha:]
- */
- @property (nonatomic, strong) UIColor * endColor;
-
- /**
- *
- * @param radius 半径
- * @param angle 角度
- * @param radarLineNum 雷达线数量
- * @param hollowRadius 空心圆半径
- *
- * @return 扫描 雷达 View
- */
- + (RadarView *)scanRadarViewWithRadius:(CGFloat)radius
- angle:(int)angle
- radarLineNum:(int)radarLineNum
- hollowRadius:(CGFloat)hollowRadius;
-
-
- /**
- *
- * @param startRadius 扩散圆 起始的半径
- * @param endRadius 扩散圆 消失的半径
- * @param circleColor 扩散圆 的颜色
- *
- * @return 扩散 雷达 View
- */
- + (RadarView *)diffuseRadarViewWithStartRadius:(CGFloat)startRadius
- endRadius:(CGFloat)endRadius
- circleColor:(UIColor *)circleColor;
-
- /**
- * 展示在targerView上
- *
- * @param targerView <#targerView description#>
- */
- - (void)showTargetView:(UIView *)targerView;
-
- - (void)dismiss;
-
- /** 开始扫描动画 */
- - (void)startAnimatian;
-
- /** 停止扫描动画 */
- - (void)stopAnimation;
-
- @end
2. RadarView.m
- #import "RadarView.h"
-
- #define CenterX self.bounds.size.width*0.5
- #define CenterY self.bounds.size.height*0.5
-
- #define DefaultRadarLineColor [UIColor colorWithWhite:1 alpha:0.7]
- #define DefaultStartColor [UIColor colorWithRed:1 green:1 blue:1 alpha:0.5]
- #define DefaultEndColor [UIColor colorWithRed:1 green:1 blue:1 alpha:0]
-
- #define DefaultCircleColor [UIColor colorWithWhite:1 alpha:0.5]
-
- @interface RadarView ()
-
- #pragma mark - 扫描类型的RadarView 属性
- /** 扇形半径 */
- @property (nonatomic, assign) CGFloat sectorRadius;
- /** 扇形 角度 */
- @property (nonatomic, assign) int angle;
- /** 雷达 空心圆圈的数量 */
- @property (nonatomic, assign) int radarLineNum;
- /** 中心 空心圆的半径 (一般 这里放置一个圆形的头像) */
- @property (nonatomic, assign) int hollowRadius;
-
- #pragma mark - 扩散类型的RadarView 属性
- /** 扩散动画 起始 的半径 */
- @property (nonatomic, assign) CGFloat startRadius;
- /** 扩散动画 结束 的半径 */
- @property (nonatomic, assign) CGFloat endRadius;
- /** 圆圈的颜色 */
- @property (nonatomic, strong) UIColor * circleColor;
-
- @property (nonatomic, strong) NSTimer * timer;
-
- @property (nonatomic, assign) RadarViewType radarViewType;
-
- @end
-
- @implementation RadarView
-
- + (RadarView *)scanRadarViewWithRadius:(CGFloat)radius angle:(int)angle radarLineNum:(int)radarLineNum hollowRadius:(CGFloat)hollowRadius {
- return [[self alloc] initWithRadius:radius angle:angle radarLineNum:radarLineNum hollowRadius:hollowRadius];
- }
-
- - (instancetype)initWithRadius:(CGFloat)radius
- angle:(int)angle
- radarLineNum:(int)radarLineNum
- hollowRadius:(CGFloat)hollowRadius {
- if (self = [super init]) {
- self.radarViewType = RadarViewTypeScan;
- self.sectorRadius = radius;
- self.frame = CGRectMake(0, 0, radius*2, radius*2);
- self.angle = angle;
- self.radarLineNum = radarLineNum-1;
- self.hollowRadius = hollowRadius;
- self.backgroundColor = [UIColor clearColor];
- }
- return self;
- }
-
- + (RadarView *)diffuseRadarViewWithStartRadius:(CGFloat)startRadius endRadius:(CGFloat)endRadius circleColor:(UIColor *)circleColor {
- return [[self alloc] initWithStartRadius:startRadius endRadius:endRadius circleColor:circleColor];
- }
-
- - (instancetype)initWithStartRadius:(CGFloat)startRadius endRadius:(CGFloat)endRadius circleColor:(UIColor *)circleColor {
- if (self = [super init]) {
- self.radarViewType = RadarViewTypeDiffuse;
- self.frame = CGRectMake(0, 0, endRadius*2, endRadius*2);
- self.startRadius = startRadius;
- self.endRadius = endRadius;
- self.circleColor = circleColor;
- self.backgroundColor = [UIColor clearColor];
- }
- return self;
- }
-
- // Only override drawRect: if you perform custom drawing.
- // An empty implementation adversely affects performance during animation.
- - (void)drawRect:(CGRect)rect {
- // Drawing code
- if (_radarViewType == RadarViewTypeScan) {
- if (!_startColor) {
- _startColor = DefaultStartColor;
- }
- if (!_endColor) {
- _endColor = DefaultEndColor;
- }
- if (!_radarLineColor) {
- _radarLineColor = DefaultRadarLineColor;
- }
-
- // 画雷达线
- [self drawRadarLine];
-
- CGContextRef context = UIGraphicsGetCurrentContext();
- // 把要画的扇形 分开画,一次画1°,每次的颜色渐变
- for (int i = 0; i < _angle; i++) {
- UIColor * color = [self colorWithCurrentAngleProportion:i*1.0/_angle];
- [self drawSectorWithContext:context color:color startAngle:-90-i];
- }
- }
- }
-
- /** 画扇形 */
- - (void)drawSectorWithContext:(CGContextRef)context
- color:(UIColor *)color
- startAngle:(CGFloat)startAngle {
- //画扇形,也就画圆,只不过是设置角度的大小,形成一个扇形
- CGContextSetFillColorWithColor(context, color.CGColor);//填充颜色
- CGContextSetLineWidth(context, 0);//线的宽度
- //以self.radius为半径围绕圆心画指定角度扇形
- CGContextMoveToPoint(context, CenterX, CenterY);
- CGContextAddArc(context, CenterX, CenterY, _sectorRadius, startAngle * M_PI / 180, (startAngle-1) * M_PI / 180, 1);
- CGContextClosePath(context);
- CGContextDrawPath(context, kCGPathFillStroke); //绘制路径
- }
-
-
- /** 画雷达线 */
- - (void)drawRadarLine {
- CGFloat minRadius = (_sectorRadius-_hollowRadius)*(pow(0.618, _radarLineNum-1));
- /** 画 围着空心半径的第一个空心圆,此圆不在计数内 */
- [self drawLineWithRadius:_hollowRadius+minRadius*0.382];
-
- for (int i = 0; i < _radarLineNum; i++) {
- [self drawLineWithRadius:_hollowRadius + minRadius/pow(0.618, i)];
- }
- }
-
- /** 画空心圆 */
- - (void)drawLineWithRadius:(CGFloat)radius {
- CAShapeLayer *solidLine = [CAShapeLayer layer];
- CGMutablePathRef solidPath = CGPathCreateMutable();
- solidLine.lineWidth = 1.0f ;
- solidLine.strokeColor = _radarLineColor.CGColor;
- solidLine.fillColor = [UIColor clearColor].CGColor;
- CGPathAddEllipseInRect(solidPath, nil, CGRectMake(self.bounds.size.width*0.5-radius, self.bounds.size.height*0.5-radius, radius*2, radius*2));
- solidLine.path = solidPath;
- CGPathRelease(solidPath);
- [self.layer addSublayer:solidLine];
- }
-
- #pragma mark - 展示
- - (void)showTargetView:(UIView *)targerView {
- self.center = targerView.center;
- [targerView addSubview:self];
- }
-
- #pragma mark -
- - (void)dismiss {
- [self removeFromSuperview];
- }
-
- #pragma mark - 开始动画
- - (void)startAnimatian {
- if (_radarViewType == RadarViewTypeScan) {
- CABasicAnimation* rotationAnimation;
- rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
- rotationAnimation.toValue = [NSNumber numberWithFloat: 1 * M_PI * 2.0 ];
- rotationAnimation.duration = 2;
- rotationAnimation.cumulative = YES;
- rotationAnimation.repeatCount = INT_MAX;
- [self.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"];
- } else {
- [self diffuseAnimation];
- _timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(diffuseAnimation) userInfo:nil repeats:YES];
- }
- }
-
- #pragma mark - 结束动画
- - (void)stopAnimation {
- if (_radarViewType == RadarViewTypeScan) {
- [self.layer removeAnimationForKey:@"rotationAnimation"];
- } else {
- [_timer invalidate];
- _timer = nil;
- }
- }
-
- - (UIColor *)colorWithCurrentAngleProportion:(CGFloat)angleProportion {
- NSArray * startRGBA = [self RGBA_WithColor:_startColor];
- NSArray * endRGBA = [self RGBA_WithColor:_endColor];
- CGFloat currentR = [startRGBA[0] floatValue] - ([startRGBA[0] floatValue]-[endRGBA[0] floatValue]) * angleProportion;
- CGFloat currentG = [startRGBA[1] floatValue] - ([startRGBA[1] floatValue]-[endRGBA[1] floatValue]) * angleProportion;
- CGFloat currentB = [startRGBA[2] floatValue] - ([startRGBA[2] floatValue]-[endRGBA[2] floatValue]) * angleProportion;
- CGFloat currentA = [startRGBA[3] floatValue] - ([startRGBA[3] floatValue]-[endRGBA[3] floatValue]) * angleProportion;
- return [UIColor colorWithRed:currentR green:currentG blue:currentB alpha:currentA];
- }
-
- /**
- * 将UIColor对象解析成RGBA 值 的数组
- *
- * @param color UIColor对象,有RGBA值 初始化的
- *[UIColor colorWithRed:rValue green:gValue blue:bValue alpha:aValue]
- *
- * @return 包含RGBA值得数组[rValue, gValue, bValue, aValue]
- */
- - (NSArray *)RGBA_WithColor:(UIColor *)color {
- NSString * colorStr = [NSString stringWithFormat:@"%@", color];
- //将RGB值描述分隔成字符串
- NSArray * colorValueArray = [colorStr componentsSeparatedByString:@" "];
- NSString * R = colorValueArray[1];
- NSString * G = colorValueArray[2];
- NSString * B = colorValueArray[3];
- NSString * A = colorValueArray[4];
- return @[R, G, B, A];
- }
-
- /** 画圆 */
- - (UIImage *)drawCircle {
- UIGraphicsBeginImageContext(CGSizeMake(_endRadius*2, _endRadius*2));
- CGContextRef context = UIGraphicsGetCurrentContext();
- CGContextMoveToPoint(context, CenterX, CenterY);
- CGContextSetFillColorWithColor(context, _circleColor.CGColor);
- CGContextAddArc(context, CenterX, CenterY, _endRadius, 0, -2*M_PI, 1);
- CGContextFillPath(context);
- UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
- UIGraphicsEndImageContext();
- return img;
- }
-
- - (void)diffuseAnimation {
- UIImageView * imgView = [[UIImageView alloc] init];
- imgView.image = [self drawCircle];
- imgView.frame = CGRectMake(0, 0, _startRadius, _startRadius);
- imgView.center = CGPointMake(CenterX, CenterY);
- [self addSubview:imgView];
-
- [UIView animateWithDuration:2 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
- imgView.frame = CGRectMake(0, 0, _endRadius*2, _endRadius*2);
- imgView.center = CGPointMake(CenterX, CenterY);
- imgView.alpha = 0;
- } completion:^(BOOL finished) {
- [imgView removeFromSuperview];
- }];
- }
-
- @end
3. ViewController.m 中使用的代码:
- #import "ViewController.h"
- #import "RadarView.h"
-
- @interface ViewController ()
-
- @property (nonatomic, strong) RadarView * scanRadarView;
- @property (nonatomic, strong) RadarView * diffuseRadarView;
-
- @end
-
- @implementation ViewController
-
- - (void)viewDidLoad {
- [super viewDidLoad];
- /** 扫描 类型 RadarView */
- // _scanRadarView = [RadarView scanRadarViewWithRadius:self.view.bounds.size.width*0.5 angle:400 radarLineNum:5 hollowRadius:0];
-
- /** 扩散 类型 RadarView */
- _diffuseRadarView = [RadarView diffuseRadarViewWithStartRadius:7 endRadius:self.view.bounds.size.width*0.5 circleColor:[UIColor whiteColor]];
- }
-
- - (void)viewDidAppear:(BOOL)animated {
- [super viewDidAppear:animated];
-
- // [_scanRadarView showTargetView:self.view];
- // [_scanRadarView startAnimatian];
-
- [_diffuseRadarView showTargetView:self.view];
- [_diffuseRadarView startAnimatian];
- }
-
- - (void)didReceiveMemoryWarning {
- [super didReceiveMemoryWarning];
- // Dispose of any resources that can be recreated.
- }
-
- @end
现在定义的是能代码加载使用,等有空了,再封装一些方法能在Storyboard中直接使用。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持w3xue。