iOS自定义雷达扫描扩散动画
本文实例为大家分享了iOS实现雷达扫描扩散动画的具体代码,供大家参考,具体内容如下
自己自定义了 一个雷达扫描/扩散效果的View。
扫描View 效果如下:
扩散View 效果如下:
文章图片
【iOS自定义雷达扫描扩散动画】自定义的代码如下:
1. RadarView.h
#importtypedef 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)radiusangle:(int)angleradarLineNum:(int)radarLineNumhollowRadius:(CGFloat)hollowRadius; /** * *@param startRadius 扩散圆 起始的半径 *@param endRadius扩散圆 消失的半径 *@param circleColor 扩散圆 的颜色 * *@return 扩散 雷达 View */+ (RadarView *)diffuseRadarViewWithStartRadius:(CGFloat)startRadiusendRadius:(CGFloat)endRadiuscircleColor:(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)radiusangle:(int)angleradarLineNum:(int)radarLineNumhollowRadius:(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 codeif (_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)contextcolor:(UIColor *)colorstartAngle:(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 = https://www.it610.com/article/[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中直接使用。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
推荐阅读
- 2020-04-07vue中Axios的封装和API接口的管理
- SpringBoot调用公共模块的自定义注解失效的解决
- python自定义封装带颜色的logging模块
- iOS中的Block
- 列出所有自定义的function和view
- 记录iOS生成分享图片的一些问题,根据UIView生成固定尺寸的分享图片
- 2019-08-29|2019-08-29 iOS13适配那点事
- Hacking|Hacking with iOS: SwiftUI Edition - SnowSeeker 项目(一)
- iOS面试题--基础
- 接口|axios接口报错-参数类型错误解决