iOS中使用CAShapeLayer、UIBezierPath画
使用CAShapeLayer和UIBezierPath可以画出一下我们想要的图,出于项目需要和兴趣,本人总结了一下其基本用法
我们先说一些实现CAShapeLayer和UIBezierPath的步骤吧
1、创建出一个UIBezierPath对象
2、创建CAShapeLayer对象
3、将UIBezierPath对象的CGPath赋值给CAShapeLayer对象的path: caShapeLayer.path = bezierPath.CGPath
4、把CAShapeLayer添加到某个显示该图形的layer中
好了、暂时知道这个多,我们直接上代码吧,在代码中感受它们的强大。(大家不要笑话我的国语水平~~~)我们创建一个环形:
.h
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
@interface LGJView : UIView
{
CAShapeLayer *_trackLayer;
UIBezierPath *_trackPath;
CAShapeLayer *_progressLayer;
UIBezierPath *_progressPath;
}
@property(nonatomic,strong)UIColor *trackColor;
@property(nonatomic,strong)UIColor *progressColor;
@property(nonatomic,assign)float progress;//0-1之间的数字
@property(nonatomic,assign)float progressWidth;
-(void)setProgress:(float)progress animated:(BOOL)animated;
@end
.m
#import "LGJView.h"
@implementation LGJView
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
_trackLayer = [CAShapeLayer new];
[self.layer addSublayer:_trackLayer];
_trackLayer.fillColor = nil;
_trackLayer.frame = self.bounds;
_progressLayer = [CAShapeLayer new];
[self.layer addSublayer:_progressLayer];
_progressLayer.fillColor = nil;
_progressLayer.lineCap = kCALineCapRound;
_progressLayer.frame = self.bounds;
self.progressWidth = 5.0f;//默认是5
}
return self;
}
-(void)setProgressWidth:(float)progressWidth{
_progressWidth = progressWidth;
_trackLayer.lineWidth = _progressWidth;
_progressLayer.lineWidth = _progressWidth;
[self setBes];
[self setProg];
}
-(void)setBes{
_trackPath = [UIBezierPath bezierPathWithArcCenter:self.center radius:(self.frame.size.width-_progressWidth)/2 startAngle:0 endAngle:M_PI*2 clockwise:YES];
_trackLayer.path = _trackPath.CGPath;
}
-(void)setProg{
_progressPath = [UIBezierPath bezierPathWithArcCenter:self.center radius:(self.bounds.size.width-_progressWidth)/2 startAngle:- M_PI_2 endAngle:(M_PI *2)*self.progress clockwise:YES];
_progressLayer.path = _progressPath.CGPath;
}
-(void)setTrackColor:(UIColor *)trackColor{
_trackLayer.strokeColor = trackColor.CGColor;
}
-(void)setProgressColor:(UIColor *)progressColor{
_progressLayer.strokeColor = progressColor.CGColor;
}
-(void)setProgress:(float)progress{
_progress = progress;
[self setProg];
}
-(void)setProgress:(float)progress animated:(BOOL)animated{
}
@end
紧接着我们在ViewController.m中
#import "ViewController.h"
#import "LGJView.h"
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
LGJView *aView = [[LGJView alloc]initWithFrame:CGRectMake(100, 100, 200, 200)];
[self.view addSubview:aView];
aView.trackColor = [UIColor blackColor];
aView.progressColor = [UIColor orangeColor];
aView.progress= .7;
aView.progressWidth = 10;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
运行以上代码程序的执行结果如下:
其实UIBezierPath通过
-
(void)addArcWithCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise可以画出一段弧线。那么各个参数的含义是什么呢?
center:圆心的坐标
radius:半径
startAngle:起始的弧度
endAngle:圆弧结束的弧度
clockwise:YES为顺时针,No为逆时针
方法里面主要是理解startAngle与endAngle,刚开始我搞不清楚一段圆弧从哪算起始和终止,比如弧度为0的话,是从上下左右哪个点开始算
看了下面这张图就明了了
看出0Pi就是指圆最右边开始计算的,顺时针依次为M_PI/2,M_PI,M_PI*1.5
明白这个,用BezierPath画圆弧就简单了
比如要画上图加粗的那段就是:
UIBezierPath *path = [[UIBezierPath alloc] init];
[path addArcWithCenter:center
radius:radius
startAngle:M_PI*1.1
endAngle:M_PI*1.9
clockwise:YES];
下面我们来看几个其他的例子
- (void)viewDidLoad {
[super viewDidLoad];
// /**创建椭圆形的贝塞尔曲线*/
UIBezierPath *lgj1 = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 200, 100)];
//
// /**创建矩形的贝塞尔曲线*/
UIBezierPath *_rectPath=[UIBezierPath bezierPathWithRect:CGRectMake(0, 0, 200, 100)];
//
//
// /**创建圆形的贝塞尔曲线*/
UIBezierPath *_circlePath=[UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 100, 100)];
//
UIBezierPath *_shapePath=[UIBezierPath bezierPathWithArcCenter:CGPointMake(20, 0) radius:100 startAngle:0 endAngle:3.14*2 clockwise:YES];
/**创建带形状的图层*/
CAShapeLayer *_shapeLayer = [CAShapeLayer layer];
_shapeLayer.frame=CGRectMake(0, 0, 200, 100);
_shapeLayer.position=self.view.center;
/**注意:图层之间与贝塞尔曲线之间通过path进行关联*/
_shapeLayer.path=lgj1.CGPath;
_shapeLayer.fillColor=[UIColor redColor].CGColor;
[self.view.layer addSublayer:_shapeLayer];
}