请关注,防止你用了,我改了,有问题连个商量的人都找不到...
雷达扫描图
DDYRadarView.h
#import <UIKit/UIKit.h>
@class DDYRadarView;
@class DDYRadarPointView;
//------------------------ 数据代理 ------------------------//
@protocol DDYRadarViewDataSource <NSObject>
@optional
/** 点位数量 最大为8 */
- (NSInteger)numberOfPointInRadarView:(DDYRadarView *)radarView;
/** 点位视图 */
- (DDYRadarPointView *)radarView:(DDYRadarView *)radarView viewForIndex:(NSInteger)index;
/** 点位图片 */
- (UIImage *)radarView:(DDYRadarView *)radarView imageForIndex:(NSInteger)index;
@end
//------------------------ 视图代理 ------------------------//
@protocol DDYRadarViewDelegate <NSObject>
@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 <DDYRadarViewDataSource> dataSource;
/** 视图代理 */
@property (nonatomic, weak) id <DDYRadarViewDelegate> 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 <QuartzCore/QuartzCore.h>
//----------------------- 点位头像视图 -----------------------//
@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<MIN([self.dataSource numberOfPointInRadarView:self], 8); index++)
{
DDYRadarPointView *pointView;
if ([self.dataSource respondsToSelector:@selector(radarView:viewForIndex:)])
{
pointView = [self.dataSource radarView:self viewForIndex:index];
}
else if ([self.dataSource respondsToSelector:@selector(radarView:imageForIndex:)])
{
if ([self.dataSource radarView:self imageForIndex:index]) {
pointView = [[DDYRadarPointView alloc] init];
pointView.image = [self.dataSource radarView:self imageForIndex:index];
}
}
if (pointView) {
pointView.ddy_size = CGSizeMake(40, 40);
pointView.center = [self pointWithIndex:index];
pointView.tag = 100+index;
[pointView addTapTarget:self action:@selector(handleTopPointView:)];
[self.pointsView addSubview:pointView];
DDYBorderRadius(pointView, pointView.ddy_w/2., .7, DDY_White);
}
}
}
}
#pragma mark 点位数组
- (CGPoint)pointWithIndex:(NSInteger)index {
CGPoint points[8];
CGFloat radiusBig = _radius;
CGFloat radiusMid = ((_circleNumber-1)*_radius/_circleNumber);
points[0] = CGPointMake(self.center.x+sinf(0*M_PI_4)*radiusBig, self.center.y-cosf(0*M_PI_4)*radiusBig);
points[1] = CGPointMake(self.center.x+sinf(4*M_PI_4)*radiusBig, self.center.y-cosf(4*M_PI_4)*radiusBig);
points[2] = CGPointMake(self.center.x+sinf(6*M_PI_4)*radiusBig, self.center.y-cosf(6*M_PI_4)*radiusBig);
points[3] = CGPointMake(self.center.x+sinf(2*M_PI_4)*radiusBig, self.center.y-cosf(2*M_PI_4)*radiusBig);
points[4] = CGPointMake(self.center.x+sinf(1*M_PI_4)*radiusMid, self.center.y-cosf(1*M_PI_4)*radiusMid);
points[5] = CGPointMake(self.center.x+sinf(3*M_PI_4)*radiusMid, self.center.y-cosf(3*M_PI_4)*radiusMid);
points[6] = CGPointMake(self.center.x+sinf(7*M_PI_4)*radiusMid, self.center.y-cosf(7*M_PI_4)*radiusMid);
points[7] = CGPointMake(self.center.x+sinf(5*M_PI_4)*radiusMid, self.center.y-cosf(5*M_PI_4)*radiusMid);
return points[index];
}
- (void)handleTopPointView:(UITapGestureRecognizer *)gesture {
if ([self.delegate respondsToSelector:@selector(radarView:didSelectItemAtIndex:)]) {
[self.delegate radarView:self didSelectItemAtIndex:gesture.view.tag-100];
}
}
#pragma mark - setter
#pragma mark 同心圆半径
- (void)setRadius:(CGFloat)radius {
_radius = radius;
[self setNeedsDisplay];
}
#pragma mark 同心圆个数
- (void)setCircleNumber:(NSInteger)circleNumber {
_circleNumber = circleNumber;
[self setNeedsDisplay];
}
#pragma mark 同心圆边框颜色
- (void)setCircleColor:(UIColor *)circleColor {
_circleColor = circleColor;
[self setNeedsDisplay];
}
#pragma mark 指示器开始颜色
- (void)setIndicatorStartColor:(UIColor *)indicatorStartColor {
_indicatorStartColor = indicatorStartColor;
[self setNeedsDisplay];
}
#pragma mark 指示器结束颜色
- (void)setIndicatorEndColor:(UIColor *)indicatorEndColor {
_indicatorEndColor = indicatorEndColor;
[self setNeedsDisplay];
}
#pragma mark 是否顺时针方向
- (void)setIndicatorClockwise:(BOOL)indicatorClockwise {
_indicatorClockwise = indicatorClockwise;
[self setNeedsDisplay];
}
#pragma mark 指示器角度大小
- (void)setIndicatorAngle:(CGFloat)indicatorAngle {
_indicatorAngle = indicatorAngle;
[self setNeedsDisplay];
}
#pragma mark 指示器旋转速度
- (void)setIndicatorSpeed:(CGFloat)indicatorSpeed {
_indicatorSpeed = indicatorSpeed;
[self setNeedsDisplay];
}
#pragma mark 视图背景图片
- (void)setBackgroundImage:(UIImage *)backgroundImage {
_backgroundImage = backgroundImage;
[self setNeedsDisplay];
}
#pragma mark 显示虚分割线
- (void)setShowSeparator:(BOOL)showSeparator {
_showSeparator = showSeparator;
[self setNeedsDisplay];
}
@end
应用DDYRadarVC.m
#import "DDYRadarVC.h"
@interface DDYRadarVC ()<DDYRadarViewDataSource, DDYRadarViewDelegate>
@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 <UIKit/UIKit.h>
//------------------------ 圆形视图 ------------------------//
@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