iOS自定义雷达扫描扩散动画
程序员文章站
2022-06-16 12:33:11
本文实例为大家分享了ios实现雷达扫描扩散动画的具体代码,供大家参考,具体内容如下自己自定义了 一个雷达扫描/扩散效果的view。扫描view 效果如下:扩散view 效果如下:自定义的代码如下:1....
本文实例为大家分享了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中直接使用。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
下一篇: 有关快消品B2B领域“区域为王”的新思考