修改UIView的backedlayer为CAShapeLayer
什么叫backedlayer呢?backedlayer指的是一个View在创建好的时候就已经帮你创建好了一个与View大小一致的CALayer了,而且,这个CALayer的所有属性值的改变都不会引起动画反应,除非写在+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations这个方法里面.认识到这一点是很关键的.
效果:
源码:
ContentView.h + ContentView.m + RootViewController.m
// // ContentView.h // Progress // // Copyright (c) 2014年 Y.X. All rights reserved. // #import <UIKit/UIKit.h> @interface ContentView : UIView @property (nonatomic, assign) CGFloat progress; @end
// // ContentView.m // Progress // // Copyright (c) 2014年 Y.X. All rights reserved. // #import "ContentView.h" @interface ContentView () { CAShapeLayer *_shapeLayer; } @end @implementation ContentView - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { _shapeLayer = (CAShapeLayer *)self.layer; _shapeLayer.strokeEnd = 0.f; _shapeLayer.fillColor = [UIColor clearColor].CGColor; _shapeLayer.strokeColor = [UIColor redColor].CGColor; UIBezierPath *path = [UIBezierPath bezierPathWithRect:self.bounds]; _shapeLayer.path = path.CGPath; } return self; } + (Class)layerClass { return [CAShapeLayer class]; } @synthesize progress = _progress; - (CGFloat)progress { return _progress; } - (void)setProgress:(CGFloat)progress { if (_progress != progress) { CABasicAnimation *ani = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; ani.fromValue = [NSNumber numberWithFloat:_progress]; ani.toValue = [NSNumber numberWithFloat:progress]; ani.duration = 0.2f; _shapeLayer.strokeEnd = progress; [_shapeLayer addAnimation:ani forKey:nil]; _progress = progress; } } @end
// // RootViewController.m // Progress // // Copyright (c) 2014年 Y.X. All rights reserved. // #import "RootViewController.h" #import "ContentView.h" #import "YXGCD.h" @interface RootViewController () @property (nonatomic, strong) GCDTimer *timer; @end @implementation RootViewController - (void)viewDidLoad { [super viewDidLoad]; ContentView *layerView = [[ContentView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)]; layerView.center = self.view.center; [self.view addSubview:layerView]; _timer = [[GCDTimer alloc] initInQueue:[GCDQueue mainQueue]]; [_timer event:^{ layerView.progress = arc4random()%100 / 100.f; } timeInterval:NSEC_PER_SEC]; [_timer start]; } @end
一些需要注意的细节: