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 codeself.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 = https://www.it610.com/article/@(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 = https://www.it610.com/article/@(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 = https://www.it610.com/article/@(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{floatangle = 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实现雷达扫描效果】以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
推荐阅读
- 2020-04-07vue中Axios的封装和API接口的管理
- 关于QueryWrapper|关于QueryWrapper,实现MybatisPlus多表关联查询方式
- MybatisPlus使用queryWrapper如何实现复杂查询
- python学习之|python学习之 实现QQ自动发送消息
- 孩子不是实现父母欲望的工具——林哈夫
- opencv|opencv C++模板匹配的简单实现
- Node.js中readline模块实现终端输入
- java中如何实现重建二叉树
- iOS中的Block
- 人脸识别|【人脸识别系列】| 实现自动化妆