当前位置:首页 > 芯闻号 > 充电吧
[导读]前段时间 没事儿,自己自定义了 一个雷达扫描/扩散效果的View。扫描View 效果如下:扩散View 效果如下:自定义的代码如下:1. RadarView.h#importtypedef NS_EN



前段时间 没事儿,自己自定义了 一个雷达扫描/扩散效果的View。

扫描View 效果如下:



扩散View 效果如下:



自定义的代码如下:

1. RadarView.h


#importtypedef NS_ENUM(NSInteger, RadarViewType) {
    RadarViewTypeScan,
    RadarViewTypeDiffuse
};

@interface RadarView : UIView

/** 雷达 空心圆圈的颜色 */
@property (nonatomic, strong) UIColor * radarLineColor;
/** 扇形开始颜色 必须由RGBA值初始化
 *  [UIColor colorWithRed: green: blue: alpha:]
 */
@property (nonatomic, strong) UIColor * startColor;
/** 扇形结束颜色 必须由RGBA值初始化
 *  [UIColor colorWithRed: green: blue: alpha:]
 */
@property (nonatomic, strong) UIColor * endColor;

/**
 *
 *  @param radius       半径
 *  @param angle        角度
 *  @param radarLineNum 雷达线数量
 *  @param hollowRadius 空心圆半径
 *
 *  @return 扫描 雷达 View
 */
+ (RadarView *)scanRadarViewWithRadius:(CGFloat)radius
                                 angle:(int)angle
                          radarLineNum:(int)radarLineNum
                          hollowRadius:(CGFloat)hollowRadius;


/**
 *
 *  @param startRadius 扩散圆 起始的半径
 *  @param endRadius   扩散圆 消失的半径
 *  @param circleColor 扩散圆 的颜色
 *
 *  @return 扩散 雷达 View
 */
+ (RadarView *)diffuseRadarViewWithStartRadius:(CGFloat)startRadius
                                     endRadius:(CGFloat)endRadius
                                   circleColor:(UIColor *)circleColor;

/**
 *  展示在targerView上
 *
 *  @param targerView 
 */
- (void)showTargetView:(UIView *)targerView;

- (void)dismiss;

/** 开始扫描动画 */
- (void)startAnimatian;

/** 停止扫描动画 */
- (void)stopAnimation;

@end


2. RadarView.m


#import "RadarView.h"

#define CenterX self.bounds.size.width*0.5
#define CenterY self.bounds.size.height*0.5

#define DefaultRadarLineColor [UIColor colorWithWhite:1 alpha:0.7]
#define DefaultStartColor [UIColor colorWithRed:1 green:1 blue:1 alpha:0.5]
#define DefaultEndColor [UIColor colorWithRed:1 green:1 blue:1 alpha:0]

#define DefaultCircleColor [UIColor colorWithWhite:1 alpha:0.5]

@interface RadarView ()

#pragma mark - 扫描类型的RadarView 属性
/** 扇形半径 */
@property (nonatomic, assign) CGFloat sectorRadius;
/** 扇形 角度 */
@property (nonatomic, assign) int angle;
/** 雷达 空心圆圈的数量 */
@property (nonatomic, assign) int radarLineNum;
/** 中心 空心圆的半径 (一般 这里放置一个圆形的头像) */
@property (nonatomic, assign) int hollowRadius;

#pragma mark - 扩散类型的RadarView 属性
/** 扩散动画 起始 的半径 */
@property (nonatomic, assign) CGFloat startRadius;
/** 扩散动画 结束 的半径 */
@property (nonatomic, assign) CGFloat endRadius;
/** 圆圈的颜色 */
@property (nonatomic, strong) UIColor * circleColor;

@property (nonatomic, strong) NSTimer * timer;

@property (nonatomic, assign) RadarViewType radarViewType;

@end

@implementation RadarView

+ (RadarView *)scanRadarViewWithRadius:(CGFloat)radius angle:(int)angle radarLineNum:(int)radarLineNum hollowRadius:(CGFloat)hollowRadius {
    return [[self alloc] initWithRadius:radius angle:angle radarLineNum:radarLineNum hollowRadius:hollowRadius];
}

- (instancetype)initWithRadius:(CGFloat)radius
                         angle:(int)angle
                  radarLineNum:(int)radarLineNum
                  hollowRadius:(CGFloat)hollowRadius {
    if (self = [super init]) {
        self.radarViewType = RadarViewTypeScan;
        self.sectorRadius = radius;
        self.frame = CGRectMake(0, 0, radius*2, radius*2);
        self.angle = angle;
        self.radarLineNum = radarLineNum-1;
        self.hollowRadius = hollowRadius;
        self.backgroundColor = [UIColor clearColor];
    }
    return self;
}

+ (RadarView *)diffuseRadarViewWithStartRadius:(CGFloat)startRadius endRadius:(CGFloat)endRadius circleColor:(UIColor *)circleColor {
    return [[self alloc] initWithStartRadius:startRadius endRadius:endRadius circleColor:circleColor];
}

- (instancetype)initWithStartRadius:(CGFloat)startRadius endRadius:(CGFloat)endRadius circleColor:(UIColor *)circleColor {
    if (self = [super init]) {
        self.radarViewType = RadarViewTypeDiffuse;
        self.frame = CGRectMake(0, 0, endRadius*2, endRadius*2);
        self.startRadius = startRadius;
        self.endRadius = endRadius;
        self.circleColor = circleColor;
        self.backgroundColor = [UIColor clearColor];
    }
    return self;
}

// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
    if (_radarViewType == RadarViewTypeScan) {
        if (!_startColor) {
            _startColor = DefaultStartColor;
        }
        if (!_endColor) {
            _endColor = DefaultEndColor;
        }
        if (!_radarLineColor) {
            _radarLineColor = DefaultRadarLineColor;
        }
        
        // 画雷达线
        [self drawRadarLine];
        
        CGContextRef context = UIGraphicsGetCurrentContext();
        // 把要画的扇形 分开画,一次画1°,每次的颜色渐变
        for (int i = 0; i < _angle; i++) {
            UIColor * color = [self colorWithCurrentAngleProportion:i*1.0/_angle];
            [self drawSectorWithContext:context color:color startAngle:-90-i];
        }
    }
}

/** 画扇形 */
- (void)drawSectorWithContext:(CGContextRef)context
                        color:(UIColor *)color
                   startAngle:(CGFloat)startAngle {
    //画扇形,也就画圆,只不过是设置角度的大小,形成一个扇形
    CGContextSetFillColorWithColor(context, color.CGColor);//填充颜色
    CGContextSetLineWidth(context, 0);//线的宽度
    //以self.radius为半径围绕圆心画指定角度扇形
    CGContextMoveToPoint(context, CenterX, CenterY);
    CGContextAddArc(context, CenterX, CenterY, _sectorRadius, startAngle * M_PI / 180, (startAngle-1) * M_PI / 180, 1);
    CGContextClosePath(context);
    CGContextDrawPath(context, kCGPathFillStroke); //绘制路径
}


/** 画雷达线 */
- (void)drawRadarLine {
    CGFloat minRadius = (_sectorRadius-_hollowRadius)*(pow(0.618, _radarLineNum-1));
    /** 画 围着空心半径的第一个空心圆,此圆不在计数内 */
    [self drawLineWithRadius:_hollowRadius+minRadius*0.382];
    
    for (int i = 0; i < _radarLineNum; i++) {
        [self drawLineWithRadius:_hollowRadius + minRadius/pow(0.618, i)];
    }
}

/** 画空心圆 */
- (void)drawLineWithRadius:(CGFloat)radius {
    CAShapeLayer *solidLine =  [CAShapeLayer layer];
    CGMutablePathRef solidPath =  CGPathCreateMutable();
    solidLine.lineWidth = 1.0f ;
    solidLine.strokeColor = _radarLineColor.CGColor;
    solidLine.fillColor = [UIColor clearColor].CGColor;
    CGPathAddEllipseInRect(solidPath, nil, CGRectMake(self.bounds.size.width*0.5-radius, self.bounds.size.height*0.5-radius, radius*2, radius*2));
    solidLine.path = solidPath;
    CGPathRelease(solidPath);
    [self.layer addSublayer:solidLine];
}

#pragma mark - 展示
- (void)showTargetView:(UIView *)targerView {
    self.center = targerView.center;
    [targerView addSubview:self];
}

#pragma mark - 
- (void)dismiss {
    [self removeFromSuperview];
}

#pragma mark - 开始动画
- (void)startAnimatian {
    if (_radarViewType == RadarViewTypeScan) {
        CABasicAnimation* rotationAnimation;
        rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
        rotationAnimation.toValue = [NSNumber numberWithFloat: 1 * M_PI * 2.0 ];
        rotationAnimation.duration = 2;
        rotationAnimation.cumulative = YES;
        rotationAnimation.repeatCount = INT_MAX;
        [self.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"];
    } else {
        [self diffuseAnimation];
        _timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(diffuseAnimation) userInfo:nil repeats:YES];
    }
}

#pragma mark - 结束动画
- (void)stopAnimation {
    if (_radarViewType == RadarViewTypeScan) {
        [self.layer removeAnimationForKey:@"rotationAnimation"];
    } else {
        [_timer invalidate];
        _timer = nil;
    }
}

- (UIColor *)colorWithCurrentAngleProportion:(CGFloat)angleProportion {
    NSArray * startRGBA = [self RGBA_WithColor:_startColor];
    NSArray * endRGBA = [self RGBA_WithColor:_endColor];
    CGFloat currentR = [startRGBA[0] floatValue] - ([startRGBA[0] floatValue]-[endRGBA[0] floatValue]) * angleProportion;
    CGFloat currentG = [startRGBA[1] floatValue] - ([startRGBA[1] floatValue]-[endRGBA[1] floatValue]) * angleProportion;
    CGFloat currentB = [startRGBA[2] floatValue] - ([startRGBA[2] floatValue]-[endRGBA[2] floatValue]) * angleProportion;
    CGFloat currentA = [startRGBA[3] floatValue] - ([startRGBA[3] floatValue]-[endRGBA[3] floatValue]) * angleProportion;
    return [UIColor colorWithRed:currentR green:currentG blue:currentB alpha:currentA];
}

/**
 *  将UIColor对象解析成RGBA 值 的数组
 *
 *  @param color UIColor对象,有RGBA值 初始化的
 *[UIColor colorWithRed:rValue green:gValue blue:bValue alpha:aValue]
 *
 *  @return 包含RGBA值得数组[rValue, gValue, bValue, aValue]
 */
- (NSArray *)RGBA_WithColor:(UIColor *)color {
    NSString * colorStr = [NSString stringWithFormat:@"%@", color];
    //将RGB值描述分隔成字符串
    NSArray * colorValueArray = [colorStr componentsSeparatedByString:@" "];
    NSString * R = colorValueArray[1];
    NSString * G = colorValueArray[2];
    NSString * B = colorValueArray[3];
    NSString * A = colorValueArray[4];
    return @[R, G, B, A];
}

/** 画圆 */
- (UIImage *)drawCircle {
    UIGraphicsBeginImageContext(CGSizeMake(_endRadius*2, _endRadius*2));
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextMoveToPoint(context, CenterX, CenterY);
    CGContextSetFillColorWithColor(context, _circleColor.CGColor);
    CGContextAddArc(context, CenterX, CenterY, _endRadius, 0, -2*M_PI, 1);
    CGContextFillPath(context);
    UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return img;
}

- (void)diffuseAnimation {
    UIImageView * imgView = [[UIImageView alloc] init];
    imgView.image = [self drawCircle];
    imgView.frame = CGRectMake(0, 0, _startRadius, _startRadius);
    imgView.center = CGPointMake(CenterX, CenterY);
    [self addSubview:imgView];
    
    [UIView animateWithDuration:2 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
        imgView.frame = CGRectMake(0, 0, _endRadius*2, _endRadius*2);
        imgView.center = CGPointMake(CenterX, CenterY);
        imgView.alpha = 0;
    } completion:^(BOOL finished) {
        [imgView removeFromSuperview];
    }];
}

@end


3. ViewController.m 中使用的代码:


#import "ViewController.h"
#import "RadarView.h"

@interface ViewController ()

@property (nonatomic, strong) RadarView * scanRadarView;
@property (nonatomic, strong) RadarView * diffuseRadarView;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    /** 扫描 类型 RadarView */
//    _scanRadarView = [RadarView scanRadarViewWithRadius:self.view.bounds.size.width*0.5 angle:400 radarLineNum:5 hollowRadius:0];
    
    /** 扩散 类型 RadarView */
    _diffuseRadarView = [RadarView diffuseRadarViewWithStartRadius:7 endRadius:self.view.bounds.size.width*0.5 circleColor:[UIColor whiteColor]];
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    
//    [_scanRadarView showTargetView:self.view];
//    [_scanRadarView startAnimatian];
    
    [_diffuseRadarView showTargetView:self.view];
    [_diffuseRadarView startAnimatian];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end


现在定义的是能代码加载使用,等有空了,再封装一些方法能在Storyboard中直接使用。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭