iOS自定義雷達(dá)掃描擴(kuò)散動(dòng)畫
本文實(shí)例為大家分享了iOS實(shí)現(xiàn)雷達(dá)掃描擴(kuò)散動(dòng)畫的具體代碼,供大家參考,具體內(nèi)容如下
自己自定義了 一個(gè)雷達(dá)掃描/擴(kuò)散效果的View。
掃描View 效果如下:

擴(kuò)散View 效果如下:

自定義的代碼如下:
1. RadarView.h
#import <UIKit/UIKit.h>
typedef NS_ENUM(NSInteger, RadarViewType) {
RadarViewTypeScan,
RadarViewTypeDiffuse
};
@interface RadarView : UIView
/** 雷達(dá) 空心圓圈的顏色 */
@property (nonatomic, strong) UIColor * radarLineColor;
/** 扇形開始顏色 必須由RGBA值初始化
* [UIColor colorWithRed: green: blue: alpha:]
*/
@property (nonatomic, strong) UIColor * startColor;
/** 扇形結(jié)束顏色 必須由RGBA值初始化
* [UIColor colorWithRed: green: blue: alpha:]
*/
@property (nonatomic, strong) UIColor * endColor;
/**
*
* @param radius 半徑
* @param angle 角度
* @param radarLineNum 雷達(dá)線數(shù)量
* @param hollowRadius 空心圓半徑
*
* @return 掃描 雷達(dá) View
*/
+ (RadarView *)scanRadarViewWithRadius:(CGFloat)radius
angle:(int)angle
radarLineNum:(int)radarLineNum
hollowRadius:(CGFloat)hollowRadius;
/**
*
* @param startRadius 擴(kuò)散圓 起始的半徑
* @param endRadius 擴(kuò)散圓 消失的半徑
* @param circleColor 擴(kuò)散圓 的顏色
*
* @return 擴(kuò)散 雷達(dá) View
*/
+ (RadarView *)diffuseRadarViewWithStartRadius:(CGFloat)startRadius
endRadius:(CGFloat)endRadius
circleColor:(UIColor *)circleColor;
/**
* 展示在targerView上
*
* @param targerView <#targerView description#>
*/
- (void)showTargetView:(UIView *)targerView;
- (void)dismiss;
/** 開始掃描動(dòng)畫 */
- (void)startAnimatian;
/** 停止掃描動(dòng)畫 */
- (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;
/** 雷達(dá) 空心圓圈的數(shù)量 */
@property (nonatomic, assign) int radarLineNum;
/** 中心 空心圓的半徑 (一般 這里放置一個(gè)圓形的頭像) */
@property (nonatomic, assign) int hollowRadius;
#pragma mark - 擴(kuò)散類型的RadarView 屬性
/** 擴(kuò)散動(dòng)畫 起始 的半徑 */
@property (nonatomic, assign) CGFloat startRadius;
/** 擴(kuò)散動(dòng)畫 結(jié)束 的半徑 */
@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;
}
// 畫雷達(dá)線
[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 {
//畫扇形,也就畫圓,只不過是設(shè)置角度的大小,形成一個(gè)扇形
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); //繪制路徑
}
/** 畫雷達(dá)線 */
- (void)drawRadarLine {
CGFloat minRadius = (_sectorRadius-_hollowRadius)*(pow(0.618, _radarLineNum-1));
/** 畫 圍著空心半徑的第一個(gè)空心圓,此圓不在計(jì)數(shù)內(nèi) */
[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 - 開始動(dòng)畫
- (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 - 結(jié)束動(dòng)畫
- (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對(duì)象解析成RGBA 值 的數(shù)組
*
* @param color UIColor對(duì)象,有RGBA值 初始化的
*[UIColor colorWithRed:rValue green:gValue blue:bValue alpha:aValue]
*
* @return 包含RGBA值得數(shù)組[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];
/** 擴(kuò)散 類型 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
現(xiàn)在定義的是能代碼加載使用,等有空了,再封裝一些方法能在Storyboard中直接使用。
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
詳解使用jquery.i18n.properties 實(shí)現(xiàn)web前端國際化
本篇文章主要介紹了使用jquery.i18n.properties 實(shí)現(xiàn)web前端國際化,具有一定的參考價(jià)值,有興趣的可以了解一下2017-07-07
iOS開發(fā)狀態(tài)欄及設(shè)置功能全面詳解
這篇文章主要為大家介紹了iOS開發(fā)狀態(tài)欄及設(shè)置功能全面詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06
iOS應(yīng)用腳本重簽名的實(shí)現(xiàn)方法
這篇文章主要介紹了iOS應(yīng)用腳本重簽名的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-01-01
AVFoundation AVCaptureSession媒體捕捉
這篇文章主要為大家介紹了ios開發(fā)AVFoundation AVCaptureSession媒體捕捉詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10
IOS 中 new 和 alloc init 的對(duì)比
這篇文章主要介紹了IOS 中 new 和 alloc init 的區(qū)別的相關(guān)資料,需要的朋友可以參考下2017-02-02
講解iOS開發(fā)中UITableView列表設(shè)計(jì)的基本要點(diǎn)
這篇文章主要介紹了講解iOS開發(fā)中UITableView列表設(shè)計(jì)的基本要點(diǎn),其中對(duì)列表行操作的常用操作舉例是iOS開發(fā)中經(jīng)常用到的基礎(chǔ),需要的朋友可以參考下2016-01-01

