iOS自定義雷達掃描擴散動畫
本文實例為大傢分享瞭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中直接使用。
以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。
推薦閱讀:
- iOS UIBezierPath實現餅狀圖
- iOS實現雷達掃描效果
- iOS文本的多語言適配以及實踐指南
- iOS開發TableView網絡請求及展示預加載實現示例
- UICollectionView 實現圖片瀏覽效果