雷达和脉冲扫描图

雷达和脉冲扫描图_第1张图片
DDYRadarView.png
雷达和脉冲扫描图_第2张图片
DDYPulseView.png

请关注,防止你用了,我改了,有问题连个商量的人都找不到...

雷达扫描图

DDYRadarView.h

#import 

@class DDYRadarView;
@class DDYRadarPointView;

//------------------------ 数据代理 ------------------------//
@protocol DDYRadarViewDataSource 
@optional
/** 点位数量 最大为8 */
- (NSInteger)numberOfPointInRadarView:(DDYRadarView *)radarView;
/** 点位视图 */
- (DDYRadarPointView *)radarView:(DDYRadarView *)radarView viewForIndex:(NSInteger)index;
/** 点位图片 */
- (UIImage *)radarView:(DDYRadarView *)radarView imageForIndex:(NSInteger)index;

@end

//------------------------ 视图代理 ------------------------//
@protocol DDYRadarViewDelegate 
@optional
/** 点击点位回调 */
- (void)radarView:(DDYRadarView *)radarView didSelectItemAtIndex:(NSInteger)index;

@end

//----------------------- 点位头像视图 -----------------------//
@interface DDYRadarPointView : UIView

@property (nonatomic, strong) UIImage *image;

@end

//------------------------ 扇形指示器 ------------------------//
@interface DDYRadarIndicatorView : UIView

@end

//------------------------- 雷达视图 -------------------------//
@interface DDYRadarView : UIView

/** 数据源代理 */
@property (nonatomic, weak) id  dataSource;
/** 视图代理 */
@property (nonatomic, weak) id  delegate;

/** 同心圆半径 */
@property (nonatomic, assign) CGFloat radius;
/** 同心圆个数 */
@property (nonatomic, assign) NSInteger circleNumber;
/** 同心圆边框颜色 */
@property (nonatomic, strong) UIColor *circleColor;
/** 指示器开始颜色 */
@property (nonatomic, strong) UIColor *indicatorStartColor;
/** 指示器结束颜色 */
@property (nonatomic, strong) UIColor *indicatorEndColor;
/** 是否顺时针方向 */
@property (nonatomic, assign) BOOL indicatorClockwise;
/** 指示器角度大小 */
@property (nonatomic, assign) CGFloat indicatorAngle;
/** 指示器旋转速度 */
@property (nonatomic, assign) CGFloat indicatorSpeed;
/** 视图背景图片 */
@property (nonatomic, strong) UIImage *backgroundImage;
/** 显示虚分割线 */
@property (nonatomic, assign) BOOL showSeparator;

/** 雷达视图对象 */
+ (instancetype)radarView;
/** 开始动画 */
- (void)startScanAnimation;
/** 结束动画 */
- (void)stopScanAnimation;
/** 刷新以展示数据 */
- (void)reloadData;

@end

DDYRadarView.m

#import "DDYRadarView.h"
#import 

//----------------------- 点位头像视图 -----------------------//
@implementation DDYRadarPointView

- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];
    [_image drawInRect:self.bounds];
}

- (void)setImage:(UIImage *)image {
    _image = image;
    [self setNeedsDisplay];
}

@end

//------------------------ 扇形指示器 ------------------------//
@interface DDYRadarIndicatorView ()
/** 半径 */
@property (nonatomic, assign) CGFloat radius;
/** 指示器开始颜色 */
@property (nonatomic, strong) UIColor *startColor;
/** 指示器结束颜色 */
@property (nonatomic, strong) UIColor *endColor;
/** 指示器角度 */
@property (nonatomic, assign) CGFloat angle;
/** 是否是否顺时针 */
@property (nonatomic, assign) BOOL clockwise;

@end

@implementation DDYRadarIndicatorView

- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];
    // 画布
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    // 渐变色
    const CGFloat *startColorComponents = CGColorGetComponents(_startColor.CGColor);
    const CGFloat *endColorComponents = CGColorGetComponents(_endColor.CGColor);
    for (int i=0; i<_angle; i++) {
        CGFloat ratio = (_clockwise?(_angle-i):i)/_angle;
        CGFloat r = startColorComponents[0] - (startColorComponents[0]-endColorComponents[0])*ratio;
        CGFloat g = startColorComponents[1] - (startColorComponents[1]-endColorComponents[1])*ratio;
        CGFloat b = startColorComponents[2] - (startColorComponents[2]-endColorComponents[2])*ratio;
        CGFloat a = startColorComponents[3] - (startColorComponents[3]-endColorComponents[3])*ratio;
        
        // 画扇形
        CGContextSetFillColorWithColor(context, DDYColor(r, g, b, a).CGColor);
        CGContextSetLineWidth(context, 0);
        CGContextMoveToPoint(context, self.center.x, self.center.y);
        CGContextAddArc(context, self.center.x, self.center.y, _radius,  i*M_PI/180, (i + (_clockwise?-1:1))*M_PI/180, _clockwise);
        CGContextDrawPath(context, kCGPathFillStroke);
    }
}

@end

//------------------------- 雷达视图 -------------------------//
@interface DDYRadarView ()

@property (nonatomic, strong) DDYRadarIndicatorView *indicatorView;

@property (nonatomic, strong) UIView *pointsView;

@end

@implementation DDYRadarView

+ (instancetype)radarView {
    return [[self alloc] initWithFrame:[UIScreen mainScreen].bounds];
}

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        [self prepare];
        [self addSubview:self.indicatorView];
    }
    return self;
}

- (void)prepare {
    _radius = self.ddy_w/2.-20;
    _circleNumber = 3;
    _circleColor = DDY_White;
    _indicatorStartColor = DDY_Blue;
    _indicatorEndColor = DDY_ClearColor;
    _indicatorClockwise = YES;
    _indicatorAngle = 360;
    _indicatorSpeed = 90;
    _backgroundImage = [UIImage imageWithColor:DDY_Gray size:DDYSCREENSIZE];
    _showSeparator = YES;
}

- (DDYRadarIndicatorView *)indicatorView {
    if (!_indicatorView) {
        _indicatorView = [[DDYRadarIndicatorView alloc] initWithFrame:self.bounds];
        _indicatorView.backgroundColor = DDY_ClearColor;
    }
    return _indicatorView;
}

- (void)resetIndicatorView {
    _indicatorView.radius = _radius;
    _indicatorView.angle = _indicatorAngle;
    _indicatorView.clockwise = _indicatorClockwise;
    _indicatorView.startColor = _indicatorStartColor;
    _indicatorView.endColor = _indicatorEndColor;
}

- (UIView *)pointsView {
    if (!_pointsView) {
        _pointsView = [[UIView alloc] initWithFrame:self.bounds].viewBGColor(DDY_ClearColor);
        [self insertSubview:_pointsView aboveSubview:self.indicatorView];
    }
    return _pointsView;
}

- (void)drawCircle {
    CGContextRef context = UIGraphicsGetCurrentContext();
    for (int i=0; i<_circleNumber; i++) {
        CGContextSetStrokeColorWithColor(context, _circleColor.CGColor);
        CGContextSetLineWidth(context, 1.);
        CGContextAddArc(context, self.center.x, self.center.y, _radius*(i+1)/_circleNumber, 0, 2*M_PI, 0);
        CGContextDrawPath(context, kCGPathStroke);
    }
}

- (void)drawSeparator {
    // 绘制
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetStrokeColorWithColor(context, _circleColor.CGColor);
    CGContextSetLineWidth(context, .7);
    CGFloat length1[] = {5, 5};
    CGContextSetLineDash(context, 0, length1, 2);
    
    for (int i=0; i<4; i++) {
        CGContextMoveToPoint(context, self.center.x+sinf(i*M_PI_4)*_radius, self.center.y-cosf(i*M_PI_4)*_radius);
        CGContextAddLineToPoint(context, self.center.x+sinf((i+4)*M_PI_4)*_radius, self.center.y-cosf((i+4)*M_PI_4)*_radius);
    }
    CGContextStrokePath(context);
}

- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];
    [_backgroundImage drawInRect:self.bounds];
    [self resetIndicatorView];
    [self drawCircle];
    [self drawSeparator];
}

- (void)startScanAnimation {
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    animation.toValue = [NSNumber numberWithFloat:(_indicatorClockwise?1:-1) * M_PI * 2.];
    animation.duration = 360.f/_indicatorSpeed;
    animation.cumulative = YES;
    animation.repeatCount = INT_MAX;
    animation.removedOnCompletion = NO;
    animation.fillMode = kCAFillModeForwards;
    [self.indicatorView.layer addAnimation:animation forKey:@"rotationAnimation"];
}

- (void)stopScanAnimation {
    [self.indicatorView.layer removeAnimationForKey:@"rotationAnimation"];
}

#pragma mark 刷新以展示数据
- (void)reloadData
{
    [self.pointsView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
    
    if ([self.dataSource respondsToSelector:@selector(numberOfPointInRadarView:)])
    {
        for (int index=0; index

应用DDYRadarVC.m

#import "DDYRadarVC.h"

@interface DDYRadarVC ()

@property (nonatomic, strong) DDYRadarView *radarView;

@end

@implementation DDYRadarVC

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self.radarView startScanAnimation];
    [self.radarView reloadData];
    [self addObserverActive];
}

- (DDYRadarView *)radarView {
    if (!_radarView) {
        _radarView = [DDYRadarView radarView];
        _radarView.dataSource = self;
        _radarView.delegate = self;
        [self.view addSubview:self.radarView];
    }
    return _radarView;
}

- (NSInteger)numberOfPointInRadarView:(DDYRadarView *)radarView {
    return 8;
}

- (UIImage *)radarView:(DDYRadarView *)radarView imageForIndex:(NSInteger)index {
    return [UIImage imageWithColor:DDYRandomColor size:CGSizeMake(40, 40)];
}

- (void)radarView:(DDYRadarView *)radarView didSelectItemAtIndex:(NSInteger)index {
    DDYLog(@"click index:%ld",index);
}

#pragma mark 监听挂起和重新进入程序
#pragma mark 添加监听
- (void)addObserverActive
{
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillResignActive:)
                                                 name:UIApplicationWillResignActiveNotification object:nil]; //监听home键挂起.
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActive:)
                                                 name:UIApplicationDidBecomeActiveNotification object:nil];  //监听重新进入程序.
}

#pragma mark 进入前台
- (void)applicationDidBecomeActive:(UIApplication *)application
{
    [self.radarView startScanAnimation];
}

#pragma mark 挂起程序
- (void)applicationWillResignActive:(UIApplication *)application
{
    [self.radarView stopScanAnimation];
}

@end

脉冲扫描图

DDYPulseView.h

#import 

//------------------------ 圆形视图 ------------------------//
@interface DDYPulseCircleView : UIView

@end

//------------------------ 脉冲视图 ------------------------//
@interface DDYPulseView : UIView

/** 填充颜色 */
@property (nonatomic, strong) UIColor *fillColor;
/** 线条颜色 */
@property (nonatomic, strong) UIColor *strokeColor;
/** 最小圆半径 */
@property (nonatomic, assign) CGFloat minRadius;

/** 创建对象 */
+ (instancetype)pulseView;

/** 开始动画 */
- (void)startAnimation;

/** 结束动画 */
 - (void)stopAnimation;

@end

DDYPulseView.m

#import "DDYPulseView.h"

//------------------------ 圆形视图 ------------------------//
@interface DDYPulseCircleView ()
/** 填充颜色 */
@property (nonatomic, strong) UIColor *fillColor;
/** 线条颜色 */
@property (nonatomic, strong) UIColor *strokeColor;
/** 初始最小半径 */
@property (nonatomic, assign) CGFloat minRadius;

@end

@implementation DDYPulseCircleView

- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetStrokeColorWithColor(context, _strokeColor.CGColor);
    CGContextSetFillColorWithColor(context, _fillColor.CGColor);
    CGContextAddArc(context, self.center.x, self.center.y, _minRadius, 0, 2*M_PI, 0);
    CGContextFillPath(context);
    CGContextDrawPath(context, kCGPathStroke);
}

@end

//------------------------ 脉冲视图 ------------------------//
@interface DDYPulseView ()

@property (strong, nonatomic) NSTimer *timer;

@end

@implementation DDYPulseView

+ (instancetype)pulseView {
    return [[self alloc] initWithFrame:[UIScreen mainScreen].bounds];
}

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        [self prepare];
    }
    return self;
}

- (void)prepare {
    _fillColor = [UIColor colorWithRed:23/255.0 green:1.0 blue:1.0 alpha:1.0];
    _strokeColor = [UIColor colorWithRed:23/255.0 green:1.0 blue:1.0 alpha:1.0];
    _minRadius = 30;
}

#pragma mark 开启定时器 开始动画
- (void)startAnimation {
    [self stopAnimation];
    self.timer = [NSTimer scheduledTimerWithTimeInterval:0.6 target:self selector:@selector(radarAnimation) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
}

#pragma mark 结束动画
- (void)stopAnimation {
    if (self.timer) {
        [self.timer invalidate];
        self.timer = nil;
    }
}

#pragma mark 扫描动画
- (void)radarAnimation
{
    DDYPulseCircleView *circleView = [[DDYPulseCircleView alloc] initWithFrame:self.bounds];
    circleView.backgroundColor = DDY_ClearColor;
    circleView.fillColor = _fillColor;
    circleView.strokeColor = _strokeColor;
    circleView.minRadius = _minRadius;
    [self addSubview:circleView];
    
    [UIView animateWithDuration:3 animations:^{
        circleView.transform = CGAffineTransformScale(circleView.transform, DDYSCREENW/2/30, DDYSCREENW/2/30);
        circleView.alpha = 0;
    } completion:^(BOOL finished) {
        [circleView removeFromSuperview];
    }];
}

#pragma mark - setter
#pragma mark 填充色
- (void)setFillColor:(UIColor *)fillColor {
    _fillColor = fillColor;
    [self startAnimation];
}

#pragma mark 同心圆线条颜色
- (void)setStrokeColor:(UIColor *)strokeColor {
    _strokeColor = strokeColor;
    [self startAnimation];
}

#pragma mark 最小圆半径
- (void)setMinRadius:(CGFloat)minRadius {
    _minRadius = minRadius;
    [self startAnimation];
}

- (void)dealloc {
    [self stopAnimation];
}

@end

应用 DDYPulseVC.m

#import "DDYPulseVC.h"

@interface DDYPulseVC ()

@property (nonatomic, strong) DDYPulseView *pulseView;

@end

@implementation DDYPulseVC

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.pulseView startAnimation];
    self.pulseView.fillColor = APP_MAIN_COLOR;
    self.pulseView.strokeColor = APP_MAIN_COLOR;
    self.pulseView.minRadius = 30;
}

- (DDYPulseView *)pulseView {
    if (!_pulseView) {
        _pulseView = [DDYPulseView pulseView];
        [self.view addSubview:_pulseView];
    }
    return _pulseView;
}

@end

码农不易点星星 scan DDYRadarView code
码农不易点星星 scan DDYPulseView code

你可能感兴趣的:(雷达和脉冲扫描图)