
分析:彩虹七种颜色,如果你做过弧形进度条,实现彩虹非常简单。
我使用自定义的CAShapeLayer,没有采用UIView drawRect绘制,也没有使用UIView。由于只实现动画,不存在交互,CALayer比UIView有更好的性能。drawRect绘制属于软件绘制,比较耗内存。
另外绘制圆的时候需要转成π,clockwise YES为顺时针、NO为逆时针。图中绘制的区域是π到3/2π。
iOS动画是有渐变效果和缓冲效果的:
CATransition *transition = [CATransition animation];
transition.type = kCATransitionFade;
transition.duration = 0.5;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
self.actions = @{@"path": transition};
彩虹七种颜色,绘制七种弧度。下面直接贴代码:
//RainbowShapeLayerHeader.h代码
#define rainbow_lineWidth 4
#define rainbow_grow_rate 0.25
#import "RainbowShapeLayer.h"
#import "RainbowShapeLayerHeader.h"
@interface RainbowShapeLayer()
{
CAShapeLayer * _shapeLayer;
UIColor * _strokeColor;
}
@end
@implementation RainbowShapeLayer
- (instancetype)initWithStrokeColor:(UIColor *)strokeColor{
self = [super init];
if (self) {
CATransition *transition = [CATransition animation];
transition.type = kCATransitionFade;
transition.duration = 0.5;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
self.actions = @{@"path": transition};
//set the p
_strokeColor = strokeColor;
}
return self;
}
- (void)drawLineWithRadius:(CGFloat)radius endAngle:(CGFloat)endAngle{
UIBezierPath * path = [[UIBezierPath alloc] init];
[path addArcWithCenter:CGPointMake(200,300) radius:radius startAngle:M_PI endAngle:endAngle clockwise:YES];
self.fillColor = [UIColor clearColor].CGColor;
self.lineWidth = rainbow_lineWidth;
self.lineJoin = kCALineJoinRound;
self.lineCap = kCALineCapRound;
self.strokeColor = _strokeColor.CGColor;
self.path = path.CGPath;
}
@end
#import "RainbowViewController.h"
#import "RainbowShapeLayer.h"
#import "RainbowShapeLayerHeader.h"
#import "Macros.h"
@interface RainbowViewController ()
{
CGFloat _timercount;
}
@property (nonatomic,strong) NSMutableArray<RainbowShapeLayer *> * rainbowArray;
@property (nonatomic, strong) CADisplayLink * displayLink;
@end
@implementation RainbowViewController
- (void)viewDidLoad {
[super viewDidLoad];
_timercount = 5;
// Do any additional setup after loading the view.
NSArray * colors = @[RGB_COLOR(252, 79, 96),
RGB_COLOR(252, 160, 50),
RGB_COLOR(255, 251, 143),
RGB_COLOR(92, 247, 94),
RGB_COLOR(71, 157, 250),
RGB_COLOR(62, 76, 241),
RGB_COLOR(145, 66, 248)];
for (NSInteger i = colors.count-1; i>=0; i--) {
RainbowShapeLayer * rainbow = [[RainbowShapeLayer alloc] initWithStrokeColor:colors[i]];
rainbow.frame = self.view.frame;
[self.rainbowArray addObject:rainbow];
[self.view.layer addSublayer:rainbow];
}
[self drawRainbow:nil];
}
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[self startTimer];
}
- (void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
[self stopTimer];
}
- (void)drawRainbow:(CADisplayLink *)timer{
if (_timercount>=50) {
_timercount = 5;
}
for (int i = 0;i<self.rainbowArray.count;i++) {
CGFloat endAngle = M_PI+M_PI*((_timercount)/100.0);
RainbowShapeLayer * rainbowView = self.rainbowArray[i];
[rainbowView drawLineWithRadius:100+rainbow_lineWidth*i endAngle:endAngle];
_timercount += rainbow_grow_rate;
}
}
#pragma mark - timer
- (void)startTimer{
self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(drawRainbow:)];
self.displayLink.frameInterval = 3;
// [self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
[self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
[self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:UITrackingRunLoopMode];
}
- (void)stopTimer{
[self.displayLink invalidate];
self.displayLink = nil;
}
- (NSMutableArray<RainbowShapeLayer *> *)rainbowArray{
if (!_rainbowArray) {
_rainbowArray = [NSMutableArray new];
}
return _rainbowArray;
}
@end
总结:
1.文中的方法不一定是最好的,我刚开始想用渐变的,后来发现渐变只能是方形的,做不到对线条渐变,采用了多条CAShapeLayer了。虽说实现不难,但调试还是需要花点时间的,另外也是对动画的一个实践。
2.有任何问题欢迎留言交流。
网友评论