本文實例為大家分享了iOS實現雷達掃描擴散動畫的具體代碼,供大家參考,具體內容如下
自己自定義了 一個雷達掃描/擴散效果的View。
掃描View 效果如下:
擴散View 效果如下:
自定義的代碼如下:
1. RadarView.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
#import <UIKit/UIKit.h> typedef 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 <#targerView description#> */ - ( void )showTargetView:(UIView *)targerView; - ( void )dismiss; /** 開始掃描動畫 */ - ( void )startAnimatian; /** 停止掃描動畫 */ - ( void )stopAnimation; @end |
2. RadarView.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
|
#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 中使用的代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
#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中直接使用。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:https://blog.csdn.net/CBlog_life/article/details/60324262