iOS实现雷达扫描效果的方法步骤
发表于:2025-01-18 作者:千家信息网编辑
千家信息网最后更新 2025年01月18日,本篇内容介绍了"iOS实现雷达扫描效果的方法步骤"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!#im
千家信息网最后更新 2025年01月18日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安全错误
数据库的锁怎样保障安全
服务器管理员找工作
域名备案地区与服务器地区不一致
西安检察院网络安全
计算机网络技术专业求职模板
十大软件开发学校
迪科数金的软件开发怎么样
广州停车系统软件开发怎么样
服务器安全辅助软件
查询数据库数据的sql怎么写
网络技术专业顾问
鼎信 软件开发 面试
iscsi 服务器搭建
db2数据库主日志
北京百姓科服网络技术
签名服务器和时间戳服务器
李建中 数据库系统原理
首届大学生网络安全论坛
html遍历表格数据库
数据库线程安全问题
网络安全十大禁令最新
服务器为什么不能主动连接客户
认证服务器不通是什么原因
简幻欢服务器导出地图
互联网科技转化
csgo服务器炸了操控有延迟
新乡软件开发税务筹划哪些形式
海宁纬编机软件开发商
服务器2805端口不能用咋回事
mavic请限飞数据库
软件开发 需求 接单