使用CAShapeLayer与UIBezierPath可以实现不在view的drawRect方法中就画出一些想要的图形
步骤:
1、新建UIBezierPath对象bezierPath
2、新建CAShapeLayer对象caShapeLayer
3、将bezierPath的CGPath赋值给caShapeLayer的path,即caShapeLayer.path = bezierPath.CGPath
4、把caShapeLayer添加到某个显示该图形的layer中
下面的小例子是一个环形的progress代码,有具体的使用方法
.h文件:
1 #import <UIKit/UIKit.h> 2 3 @interface KACircleProgressView : UIView { 4 CAShapeLayer *_trackLayer; 5 UIBezierPath *_trackPath; 6 CAShapeLayer *_progressLayer; 7 UIBezierPath *_progressPath; 8 } 9 10 @property (nonatomic, strong) UIColor *trackColor; 11 @property (nonatomic, strong) UIColor *progressColor; 12 @property (nonatomic) float progress;//0~1之间的数 13 @property (nonatomic) float progressWidth; 14 15 - (void)setProgress:(float)progress animated:(BOOL)animated; 16 17 @end
.m文件
1 #import "KACircleProgressView.h" 2 3 @implementation KACircleProgressView 4 5 - (id)initWithFrame:(CGRect)frame 6 { 7 self = [super initWithFrame:frame]; 8 if (self) { 9 // Initialization code 10 _trackLayer = [CAShapeLayer new]; 11 [self.layer addSublayer:_trackLayer]; 12 _trackLayer.fillColor = nil; 13 _trackLayer.frame = self.bounds; 14 15 _progressLayer = [CAShapeLayer new]; 16 [self.layer addSublayer:_progressLayer]; 17 _progressLayer.fillColor = nil; 18 _progressLayer.lineCap = kCALineCapRound; 19 _progressLayer.frame = self.bounds; 20 21 //默认5 22 self.progressWidth = 5; 23 } 24 return self; 25 } 26 27 - (void)setTrack 28 { 29 _trackPath = [UIBezierPath bezierPathWithArcCenter:self.center radius:(self.bounds.size.width - _progressWidth)/ 2 startAngle:0 endAngle:M_PI * 2 clockwise:YES];; 30 _trackLayer.path = _trackPath.CGPath; 31 } 32 33 - (void)setProgress 34 { 35 _progressPath = [UIBezierPath bezierPathWithArcCenter:self.center radius:(self.bounds.size.width - _progressWidth)/ 2 startAngle:- M_PI_2 endAngle:(M_PI * 2) * _progress - M_PI_2 clockwise:YES]; 36 _progressLayer.path = _progressPath.CGPath; 37 } 38 39 40 - (void)setProgressWidth:(float)progressWidth 41 { 42 _progressWidth = progressWidth; 43 _trackLayer.lineWidth = _progressWidth; 44 _progressLayer.lineWidth = _progressWidth; 45 46 [self setTrack]; 47 [self setProgress]; 48 49 CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; 50 animation.fromValue = [NSNumber numberWithFloat:0.0f]; 51 animation.toValue = [NSNumber numberWithFloat:1.0f]; 52 animation.duration = 3.0f; 53 [_progressLayer addAnimation:animation forKey:@"myStroke"]; 54 } 55 56 - (void)setTrackColor:(UIColor *)trackColor 57 { 58 _trackLayer.strokeColor = trackColor.CGColor; 59 } 60 61 - (void)setProgressColor:(UIColor *)progressColor 62 { 63 _progressLayer.strokeColor = progressColor.CGColor; 64 } 65 66 - (void)setProgress:(float)progress 67 { 68 _progress = progress; 69 70 [self setProgress]; 71 } 72 73 - (void)setProgress:(float)progress animated:(BOOL)animated 74 { 75 76 } 77 78 /* 79 // Only override drawRect: if you perform custom drawing. 80 // An empty implementation adversely affects performance during animation. 81 - (void)drawRect:(CGRect)rect 82 { 83 // Drawing code 84 } 85 */ 86 87 @end
使用:
1 - (void)viewDidLoad 2 { 3 [super viewDidLoad]; 4 // Do any additional setup after loading the view, typically from a nib. 5 KACircleProgressView *progress = [[KACircleProgressView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)]; 6 [self.view addSubview:progress]; 7 progress.trackColor = [UIColor blackColor]; 8 progress.progressColor = [UIColor orangeColor]; 9 progress.progress = .7; 10 progress.progressWidth = 10; 11 }
[CABasicAnimation animationWithKeyPath:@"strokeEnd"] 中的keyPath不能随意更改。
check:http://stackoverflow.com/questions/7966590/iphone-core-animation-animate-a-nsbezierpath
也可以参考一份代码:https://github.com/ole/Animated-Paths 其实现的效果在code4app中有介绍http://code4app.com/ios/Animated-Paths/5020854c6803faa152000000