iOS实现雷达扫描效果的方法步骤
发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,本篇内容介绍了"iOS实现雷达扫描效果的方法步骤"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!#im
千家信息网最后更新 2026年11月02日iOS实现雷达扫描效果的方法步骤
本篇内容介绍了"iOS实现雷达扫描效果的方法步骤"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
#import@interface LTIndicatiorView : UIView@property(nonatomic,strong)UIColor *color;@property(nonatomic,assign)float repeatCount;@property(nonatomic,strong)UIColor *borderColor;@property(nonatomic,assign)float borderWidth;@end @interface LTRadarView : UIView@property(nonatomic,strong)UIColor *color;@property(nonatomic,strong)UIColor *borderColor;@property(nonatomic,assign)float borderWidth;@property(nonatomic,assign)int pulsingCount;@property(nonatomic,assign)float duration;@property(nonatomic,assign)float repeatCount;@property(nonatomic,strong)CALayer *pulsingLayer; @end
.m文件
//// LTRadarView.m// raderScan//// Created by mac on 17/2/5.// Copyright © 2017年 mac. All rights reserved.// #import "LTRadarView.h" #define Angel 15 @interface LTRadarButton : UIButton @end @implementation LTRadarButton - (void)removeFromSuperview{ [UIView beginAnimations:@"" context:nil]; [UIView setAnimationDuration:0.5]; self.transform = CGAffineTransformMakeScale(0.2, 0.2); self.alpha = 0; [UIView setAnimationDidStopSelector:@selector(callSuperRemoveFromSuperview)]; [UIView commitAnimations]; } - (void)callSuperRemoveFromSuperview{ [super removeFromSuperview];} - (id)initWithFrame:(CGRect)frame{ self = [super initWithFrame:frame]; self.alpha = 0; return self;} - (void)didMoveToWindow{ [super didMoveToWindow]; self.transform = CGAffineTransformMakeScale(0.2, 0.2); if (self.window) { [UIView animateWithDuration:0.5 animations:^{ self.transform = CGAffineTransformIdentity; self.alpha = 1; }]; } } @end @implementation LTIndicatiorView - (id)initWithFrame:(CGRect)frame{ if (self = [super initWithFrame:frame]) { _color = [UIColor greenColor]; _repeatCount = HUGE_VALF; _borderColor = [UIColor redColor]; _borderWidth = 1.0f; } return self;} // Only override drawRect: if you perform custom drawing. // An empty implementation adversely affects performance during animation. - (void)drawRect:(CGRect)rect { // Drawing code self.backgroundColor = [UIColor whiteColor]; [super drawRect:rect]; self.layer.cornerRadius = self.frame.size.height/2.0f; self.clipsToBounds = YES; self.layer.borderColor = [UIColor clearColor].CGColor; self.layer.borderWidth = 50; self.layer.masksToBounds = YES; CGContextRef context = UIGraphicsGetCurrentContext(); for (int i = 0; i < Angel; i++) { CGFloat alpha = (float)i /(float)600; CGColorRef shadowColor = [[UIColor greenColor] colorWithAlphaComponent:alpha].CGColor;//计算扇形填充颜色 CGContextSetFillColorWithColor(context, shadowColor); CGContextMoveToPoint(context, self.center.x, self.center.y);//指定员心 CGFloat startAngle = (-Angel+i+1.15)/Angel*(float)M_PI; CGFloat endAngle = (-Angel+i-1.15)/Angel*(float)M_PI;// NSLog(@"startAngle = %f endAngle = %f ,alpha = %f",startAngle,endAngle,alpha); CGContextAddArc(context, self.center.x, self.center.y, self.frame.size.height/2.0f,0, 25, 1);//画一个扇形 CGContextClosePath(context); CGContextDrawPath(context, kCGPathFill);//绘制扇形 } CGContextSetLineWidth(context, 1);//扫描线宽度 CGContextSetStrokeColorWithColor(context, [_color colorWithAlphaComponent:1].CGColor);//扫描线颜色 CGContextMoveToPoint(context, self.center.x, self.center.y); CGContextAddLineToPoint(context, self.frame.size.height, self.center.y); CGContextStrokePath(context); CGContextSetRGBStrokeColor(context,255/255.0, 255/255.0, 255/255.0, 0.1);//最外面圆颜色 CGContextSetLineWidth(context, 10);//线宽度 CGContextAddArc(context, self.center.x, self.center.y, self.frame.size.height/2.0, 0, 2*M_PI, 1);//添加一个圆 CGContextDrawPath(context, kCGPathStroke);//绘制路径 CGContextStrokePath(context);//显示绘制 //扫描动画 CABasicAnimation *rotateAnimation = [CABasicAnimation animation]; rotateAnimation.keyPath = @"transform.rotation.z"; rotateAnimation.toValue = @(2*M_PI); rotateAnimation.duration = 3; rotateAnimation.removedOnCompletion = NO; rotateAnimation.repeatCount = _repeatCount; [self.layer addAnimation:rotateAnimation forKey:@"rotate_layer"]; } @end @implementation LTRadarView{ NSMutableArray *items;} - (id)initWithFrame:(CGRect)frame{ if (self = [super initWithFrame:frame]) { items = [NSMutableArray array]; _color = [UIColor redColor]; _borderColor = [UIColor greenColor]; _pulsingCount = 3; _duration = 3; _repeatCount = HUGE_VALF; _borderWidth = 3.0f; } return self;} // Only override drawRect: if you perform custom drawing.// An empty implementation adversely affects performance during animation.- (void)drawRect:(CGRect)rect { // Drawing code [super drawRect:rect]; self.layer.cornerRadius = self.frame.size.height/2; self.clipsToBounds = YES; self.layer.borderColor = [UIColor clearColor].CGColor; self.layer.borderColor = [UIColor clearColor].CGColor; self.layer.borderWidth = 50; self.layer.masksToBounds = YES; CGContextRef ctx = UIGraphicsGetCurrentContext(); CGContextSetRGBFillColor(ctx, 0/255.0, 0/255.0, 0/255.0, 1);//圆颜色 CGContextSetLineWidth(ctx, 1);//宽度 CGContextAddArc(ctx, self.center.x, self.center.y, self.frame.size.height/2, 0, 2*M_PI, 1);//添加一个圆 CGContextDrawPath(ctx, kCGPathStroke);//绘制 CGContextStrokePath(ctx);//显示 CALayer *animationLayer = [CALayer layer]; animationLayer.frame = self.layer.frame; for (int i = 0; i < _pulsingCount; i++) { CALayer *pulsingLayer = [CALayer layer]; pulsingLayer.frame = CGRectMake(0, 0, rect.size.width, rect.size.height); pulsingLayer.borderColor = [UIColor clearColor].CGColor; pulsingLayer.borderWidth = 1; pulsingLayer.cornerRadius = rect.size.height/2; pulsingLayer.backgroundColor = [UIColor redColor].CGColor; CAAnimationGroup *animationGroup = [CAAnimationGroup animation]; animationGroup.fillMode = kCAFillModeBoth; animationGroup.beginTime = CACurrentMediaTime() + (float) i * _duration / _pulsingCount; animationGroup.duration = _duration; animationGroup.repeatCount = HUGE_VALF; animationGroup.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; animationGroup.autoreverses = NO; animationGroup.delegate = self; animationGroup.removedOnCompletion = NO; CABasicAnimation *scaleAnimation = [CABasicAnimation animation]; scaleAnimation.keyPath = @"transform.scale"; scaleAnimation.removedOnCompletion = NO; scaleAnimation.fromValue = @(0.0f); scaleAnimation.toValue = @1.0f; scaleAnimation.autoreverses = NO; CAKeyframeAnimation *opacityAnimation = [CAKeyframeAnimation animation]; opacityAnimation.keyPath = @"opacity"; opacityAnimation.values = @[@1.0,@0.75,@0.5,@0.25,@0.0]; opacityAnimation.keyTimes = @[@0.0,@0.25,@0.5,@0.75,@1]; opacityAnimation.autoreverses = NO; opacityAnimation.removedOnCompletion = NO; animationGroup.animations = @[scaleAnimation,opacityAnimation]; [pulsingLayer addAnimation:animationGroup forKey:@"pulsing"]; [animationLayer addSublayer:pulsingLayer]; } [self.layer addSublayer:animationLayer]; [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(addOrReplaceItem) userInfo:nil repeats:YES];} - (void)animation:(CALayer *)layer{ CAAnimationGroup *animationGroup = [CAAnimationGroup animation]; animationGroup.fillMode = kCAFillModeBoth; animationGroup.beginTime = CACurrentMediaTime() + 1 * _duration / _pulsingCount; animationGroup.duration = _duration; animationGroup.repeatCount = HUGE_VALF; animationGroup.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; animationGroup.autoreverses = NO; animationGroup.delegate = self; animationGroup.removedOnCompletion = NO; CABasicAnimation *scaleAnimation = [CABasicAnimation animation]; scaleAnimation.keyPath = @"transform.scale"; scaleAnimation.removedOnCompletion = NO; scaleAnimation.fromValue = @(0.0f); scaleAnimation.toValue = @1.0f; scaleAnimation.autoreverses = NO; CAKeyframeAnimation *opacityAnimation = [CAKeyframeAnimation animation]; opacityAnimation.keyPath = @"opacity"; opacityAnimation.values = @[@1.0,@0.75,@0.5,@0.25,@0.0]; opacityAnimation.keyTimes = @[@0.0,@0.25,@0.5,@0.75,@1]; opacityAnimation.autoreverses = NO; opacityAnimation.removedOnCompletion = NO; animationGroup.animations = @[scaleAnimation,opacityAnimation]; [layer addAnimation:animationGroup forKey:@"pulsing"]; } #define RandomColor [UIColor colorWithRed:arc4random_uniform(256)/255.0 green:arc4random_uniform(256)/255.0 blue:arc4random_uniform(256)/255.0 alpha:1.0]/* 生成一个在圆里面的坐标 生成的坐标要围绕中心的绿点(圆心),让我们重新翻开数学课本,看看高中数学对三角函数的定义: 在一个平面直角坐标系中,以原点为圆心,1 为半径画一个圆,这个圆交 x 轴于 A 点。以 O 为旋转中心,将 A 点逆时针旋转一定的角度α至 B 点,设此时 B 点的坐标是(x,y),那么此时 y 的值就叫做α的正弦,记作 sinα;此时 x 的值就叫做α的余弦,记作 cosα;y 与 x 的比值 y/x 就叫做α的正切,记作 tanα。 任意角三角函数 正弦sinθ=y/r, 余弦cosθ=x/r,正切tanθ=y/x,余切cotθ=x/y,正割secθ=r/x,余割cscθ=r/y 锐角三角函数 正弦sinA=a/c, 余弦cosA=b/c,正切tanA=a/b,余切cotA=b/a,正割secA=c/b,余割cscA=c/a 还有一个很重要的公式:圆的参数方程:以点O(a,b)为圆心,以r为半径的圆的参数方程是 x=a+r*cosθ, y=b+r*sinθ, (其中θ为参数) 到这里为止,思路就清晰了,以下是generateCenterPointInRadar的方法实现: */ - (CGPoint)generateCenterPointInRadar{ float angle = arc4random() % 360;//随机一个角度 float radius = arc4random() % (int)((self.bounds.size.width - 44)/2);//随机一个半径, 这里减去44是因为要把这个view显示在圆里面,如果不减44,则有可能会显示在圓外面 double x = cos(angle) * radius;//计算随机出现的一个角度的x坐标 x=a+r*cosθ r = radius, θ = angle ,a = 圆心的x坐标 double y = sin(angle) * radius;//计算随机出现的一个角度的y坐标 y=b+r*sinθ r = radius, θ = angle ,b = 圆心的y坐标 return CGPointMake(x + self.bounds.size.width / 2, y + self.bounds.size.height / 2);//x y 分别加个圆心的坐标即self.center.x.y} - (void)addOrReplaceItem{ int maxCount = 10; LTRadarButton *radarButton = [LTRadarButton buttonWithType:UIButtonTypeCustom]; radarButton.frame = CGRectMake(0, 0, 44, 44); radarButton.backgroundColor = RandomColor; radarButton.layer.cornerRadius = 44/2; do { CGPoint center = [self generateCenterPointInRadar]; radarButton.center = CGPointMake(center.x, center.y); } while ([self itemFrameIntersectsInOtherItem:radarButton.frame]); [self addSubview:radarButton]; [items addObject:radarButton]; if (items.count > maxCount) { UIView * view = [items firstObject]; [view removeFromSuperview]; [items removeObject:view]; }} /* 我们现在在生成每个item的center的时候,没有和已有的item进行比较,这是一个比较耗性能的操作,如果你的itemSize过大,maxCount过多,这甚至能导致死循环,如果是那样的话,你可能在对itemSize以及maxCount做出限制的同时,也对循环的数量也进行控制,如果在生成一个item的center的时候,进行了过多的循环,就可以视为进入死循环了,在这种情况下,你只能重新计算已有的centers。这里不考虑这种极端情况,因为目前的itemSize和maxCount的配合,不会出现死循环。 我们添加一个itemFrameIntersectsInOtherItem私有方法来判断是否和之前生成的center有了重叠: */- (BOOL)itemFrameIntersectsInOtherItem:(CGRect)frame{ for (UIView *item in items) { if (CGRectIntersectsRect(item.frame, frame)) { return YES; } } return NO;}"iOS实现雷达扫描效果的方法步骤"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!
循环
颜色
方法
宽度
情况
扇形
生成
效果
步骤
雷达
内容
扫描线
时候
更多
知识
过多
实用
学有所成
接下来
那样的话
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
中关村互联网 科技集团
美国互联网科技巨头监管
互联网与科技金融数据
网络科技有限互联网
互联网 科技公司
互联网科技ppt模板
卫星互联网科技股票
中国科技互联网公司收入
温州喔噻互联网科技有限公司
欧洲十大科技互联网公司
广州恒生互联网科技有限
互联网科技有哪些公司
呼和浩特新华互联网科技学院
互联网金融科技展
西安小鹰速贷互联网科技有限公司
中和天地互联网科技有限公司
广州互联网高科技取餐柜
江苏互联网智能科技产品出厂价
互联网的黑科技实验室
宁波允成互联网科技有限公司
重生之互联网科技帝国
互联网科技卖菜
互联网金融与金融科技
互联网科技作文
凡科互联网科技
衡水科技产业互联网平台
老年人脱离互联网科技的作文
移动互联网科技公司
三亚科技创新互联网基地
深圳互联网科技园地址