iOS开发 UIBezierPath曲线动画

来源:互联网 发布:铜镀铬和不锈钢 知乎 编辑:程序博客网 时间:2024/05/23 12:32
基础知识
使用UIBezierPath可以创建基于矢量的路径 此类是Core Graphics的封装。使用这个类可以定义简单的形状 如椭圆、矩形或者有多个直线和曲线段组成的形状等。
UIBezierPath是CGPathRef数据类型的封装,如果是基于矢量形状的路径,都用直线和曲线去创建,我们使用直线段创建矩形和多边形,使用曲线去创建圆弧圆或者其他的复杂的曲线形状。
使用UIBezierPath画图的步骤:
1.创建一个基于UIBezierPath的对象
2.调用-moveToPoint设置初始线段的起点。
3.添加线或者曲线去定义一个或者多个子路径
4.改变UIBezierPath对象跟绘图相关的属性,如 我们可以设置画笔的属性填充样式等等。

UIBezierPath创建方法

    + (instancetype)bezierPath;

因为这个工厂方法创建的对象,我们可以根据我们的需要任意定制样式,

可以画任何我们想画的图形。

    + (instancetype)bezierPathWithRect:(CGRect)rect;

这个工厂方法根据一个矩形画贝塞尔曲线。

    + (instancetype)bezierPathWithOvalInRect:(CGRect)rect;

这个工厂方法根据一个矩形画内切曲线。通常用它来画圆或者椭圆。

    + (instancetype)bezierPathWithRoundedRect:(CGRect)rect

      cornerRadius:(CGFloat)cornerRadius;

    + (instancetype)bezierPathWithRoundedRect:(CGRect)rect

    byRoundingCorners:(UIRectCorner)corners

          cornerRadii:(CGSize)cornerRadii;

以上两个方法都可以画矩形

1.这个工厂方法画矩形 但是这个矩形是可以画圆角的 第一个参数是矩形 第二个参数是圆角大小。

2.这个工厂方法画矩形 可以指定某一个角画成圆角 可以用来给UIView扩展添加圆角方法。

    + (instancetype)bezierPathWithArcCenter:(CGPoint)center

    radius:(CGFloat)radius

      startAngle:(CGFloat)startAngle

        endAngle:(CGFloat)endAngle

        clockwise:(BOOL)clockwise;

画圆弧 参数如下

center:弧线所在圆的圆心

radius:弧线所在圆的半径

startAngle:开始角度值

 endAngle:弧线结束角度值

clockwise:是否顺时针画弧线

- (UIBezierPath *)bezierPathByReversingPath

创建 并返回一个与当前路径相反的新的贝塞尔路径对象 

    + (instancetype)bezierPathWithCGPath:(CGPathRef)CGPath;


通过一个CGPath来创建一个贝塞尔路径对象

创建路径

- (void)moveToPoint:(CGPoint)point

将接收器的当前点移动到指定位置。

- (void)addLineToPoint:(CGPoint)point

附加一条直线到接收器的路径。

- (void)addArcWithCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise

追加一个弧到接收器的路径。


- (void)addCurveToPoint:(CGPoint)endPoint controlPoint1:(CGPoint)controlPoint1 controlPoint2:(CGPoint)controlPoint2

追加一个一次Bezier曲线到接收器的路径。


- (void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint

追加一个二次Bezier曲线到接收器的路径。

- (void)closePath

关闭最近添加的子路径。


- (void)removeAllPoints

删除从接收点开始的所有的点,有效地删除所有子路径。

- (void)appendPath:(UIBezierPath *)bezierPath

追加指定的路径对象的内容到接收器的路径。

@property(nonatomic) CGPathRef CGPath

路径的核心绘图的表示。

@property(nonatomic, readonly) CGPoint currentPoint

图形路径中的当前点。(只读)



访问绘图属性

@property(nonatomic) CGFloat lineWidth

path的行宽

@property(nonatomic) CGLineCap lineCapStyle线条拐角

当填充时 路径结束点的路径形状 举例子说 圆形的顶部等。

@property(nonatomic) CGLineJoin lineJoinStyle

终点处理  

@property(nonatomic) CGFloat miterLimit

设置线段链接处的样式

@property(nonatomic) CGFloat flatness

确定弯曲路径段的绘制精度的因素。


@property(nonatomic) BOOL usesEvenOddFillRule

一个bool值 指定even-odd规则是否在path可用

- (void)setLineDash:(const CGFloat *)pattern count:(NSInteger)count phase:(CGFloat)phase

设置path的接触样式。

- (void)getLineDash:(CGFloat *)pattern count:(NSInteger*)count phase:(CGFloat *)phase

获取path的线接触样式


画路径


- (void)fill

用当前绘图属性绘制当前被路径包围的区域

- (void)fillWithBlendMode:(CGBlendMode)blendMode alpha:(CGFloat)alpha

用指定的混合模式和透明度值来描绘受接收路径所包围的区域。

- (void)stroke

利用当前绘图属性沿着接收器的路径绘制一行

- (void)strokeWithBlendMode:(CGBlendMode)blendMode alpha:(CGFloat)alpha

使用指定的混合模式和透明度值沿着接收器路径。绘制一行


裁剪路径


- (void)addClip

剪切被接收者路径包围的区域 该路径是带有剪切路径的当前绘图上下文。使得其成为我们当前的剪切路径、


检测

- (BOOL)containsPoint:(CGPoint)point

返回一个布尔值,该值指示接收器所包含的区域是否包含指定的点。

@property(readonly, getter=isEmpty) BOOL empty

一个布尔值,该值指示路径是否有任何有效的元素。(只读)

@property(nonatomic, readonly) CGRect bounds

路径的包围矩形。(只读)

提交变换


- (void)applyTransform:(CGAffineTransform)transform

用指定的仿射变换矩阵变换路径中的所有点。

常数

enum{

UIRectCornerTopLeft=1 << 0,

UIRectCornerTopRight=1 << 1,

UIRectCornerBottomLeft=1 << 2,

UIRectCornerBottomRight=1 << 3,

UIRectCornerAllCorners=~0

};

typedefNSUIntegerUIRectCorner;


矩形的角。

UIRectCornerTopLeft        左上角

UIRectCornerTopRight       右上角

UIRectCornerBottomLeft     左下角

UIRectCornerBottomRight    右下角

UIRectCornerAllCorners     所有的角。



小例子

以下方法均在drawRect方法中调用

画三角形

[objc] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. -(void)drawTriangle  
  2. {  
  3.     //创建路径对象  
  4.     UIBezierPath * path = [UIBezierPath bezierPath];  
  5.       
  6.     //path的设置  
  7.     [path moveToPoint:CGPointMake(2020)];  
  8.     [path addLineToPoint:CGPointMake(self.frame.size.width - 4020)];  
  9.     [path addLineToPoint:CGPointMake(self.frame.size.width / 2self.frame.size.height - 20)];  
  10.     //闭合曲线 调用closePath自动生成 也可以调用-addLineToPoint:生成。  
  11.     [path closePath];  
  12.       
  13.     //设置填充颜色  
  14.     UIColor * color = [UIColor redColor];  
  15.     [color set];  
  16.     [path fill];  
  17.       
  18.     //设置画笔颜色  
  19.     UIColor * strokeColor = [UIColor blueColor];  
  20.     [strokeColor set];  
  21.     //根据设置的各个点连线  
  22.     [path stroke];  
  23.   
  24.     path.lineWidth = 1.2;  
  25. }  


其中设置画笔颜色通过set方法。

如果我们需要设置填充颜色,那么需要在设置画笔颜色之前先设置填充颜色,否则画笔颜色就被填充颜色取代了。也就是说 如果要让填充颜色和画笔颜色不一样 那么必须先设置填充颜色再设置画笔颜色。



画矩形

[objc] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. -(void)drawRectangle  
  2. {  
  3.     CGRect rect = CGRectMake(3030200200);  
  4.     UIBezierPath * path = [UIBezierPath bezierPathWithRect:rect];  
  5.     path.lineWidth = 1.2;  
  6.     path.lineCapStyle = kCGLineCapRound;  
  7.     path.lineJoinStyle = kCGLineJoinBevel;  
  8.       
  9.     //设置填充颜色  
  10.     UIColor *fillColor = [UIColor greenColor];  
  11.     [fillColor set];  
  12.     [path fill];  
  13.       
  14.     UIColor *strokeColor = [UIColor blueColor];  
  15.     [strokeColor set];  
  16.     [path stroke];  
  17. }  



lineCapStyle属性是用来设置线条拐角冒的样式的

/* Line cap styles. */
typedef CF_ENUM(int32_t, CGLineCap) {    kCGLineCapButt,    kCGLineCapRound,    kCGLineCapSquare};

第一个是默认的,第二个是轻微圆角,第三个是正方形

lineJoinStyle属性是用来设置两条线连结点的样式,其中也有三个选择:

/* Line join styles. */typedef CF_ENUM(int32_t, CGLineJoin) {    kCGLineJoinMiter,    kCGLineJoinRound,    kCGLineJoinBevel};

第一个默认表示斜接,第二个圆滑衔接,第三个斜角衔接。

画圆


[objc] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. -(void)drawCircle  
  2. {  
  3.     CGRect rect = CGRectMake(2020200200);  
  4.     UIBezierPath * path = [UIBezierPath bezierPathWithOvalInRect:rect];  
  5.     //设置填充颜色  
  6.     UIColor * fillColor = [UIColor greenColor];  
  7.     [fillColor set];  
  8.     [path fill];  
  9.       
  10.     //设置画笔颜色  
  11.     UIColor * strokeColor = [UIColor blueColor];  
  12.     [strokeColor set];  
  13.     [path stroke];  
  14. }  



画椭圆

[objc] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. -(void)drawEllipse  
  2. {  
  3.     CGRect rect = CGRectMake( 2020200100);  
  4.     UIBezierPath * path = [UIBezierPath bezierPathWithOvalInRect:rect];  
  5.       
  6.     UIColor * fillColor = [UIColor redColor];  
  7.     [fillColor set];  
  8.     [path fill];  
  9.       
  10.     UIColor * strokeColor = [UIColor greenColor];  
  11.     [strokeColor set];  
  12.     [path stroke];  
  13. }  


画带圆角的矩形

[objc] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. -(void)drawRoundRect  
  2. {  
  3.     CGRect rect = CGRectMake(2020200200);  
  4.     UIBezierPath * path = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:15];  
  5.     UIColor * fillColor = [UIColor redColor];  
  6.     [fillColor set];  
  7.     [path fill];  
  8.       
  9.     UIColor * strokeColor = [UIColor greenColor];  
  10.     [strokeColor set];  
  11.     [path stroke];  
  12. }  


画指定几个圆角的矩形

[objc] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. -(void)drawSomeRoundRect  
  2. {  
  3.     CGRect rect = CGRectMake(2020200200);  
  4.     UIBezierPath * path = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:UIRectCornerBottomRight | UIRectCornerTopLeft cornerRadii:CGSizeMake(3010)];  
  5.       
  6.     UIColor * fillColor = [UIColor redColor];  
  7.     [fillColor set];  
  8.     [path fill];  
  9.       
  10.     UIColor * strokeColor = [UIColor grayColor];  
  11.     [strokeColor set];  
  12.     [path stroke];  
  13. }  


画圆弧

画弧前,我们需要了解其参考系,如下图(图片来自网络):


[objc] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. -(void)drawARCPath  
  2. {  
  3.     const CGFloat pi = M_PI;  
  4.     NSLog(@"%f",pi);  
  5.     CGPoint center = CGPointMake(self.frame.size.width * 0.5self.frame.size.height * 0.5);  
  6.     CGFloat end = DefreesToRadius(140) ;  
  7.     NSLog(@"%f",end);  
  8.     UIBezierPath * path = [UIBezierPath bezierPathWithArcCenter:center radius:100 startAngle:0 endAngle:end clockwise:YES];  
  9.       
  10.     UIColor * fillColor = [UIColor redColor];  
  11.     [fillColor set];  
  12.     [path fill];  
  13.     path.lineCapStyle = kCGLineCapRound;  
  14.     path.lineJoinStyle = kCGLineJoinRound;  
  15.     path.lineWidth = 5.0;  
  16.     UIColor * strokeColor = [UIColor blueColor];  
  17.     [strokeColor set];  
  18.     [path stroke];  
  19. }  



画二次贝塞尔曲线

先来学习一下关于控制点,如下图(图片来自网络):


- (void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint

参数说明:

endPoint:终端点<br/>
controlPoint:控制点,对于二次贝塞尔曲线,只有一个控制点

[objc] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. -(void)drawBezierPath  
  2. {  
  3.     UIBezierPath * path = [UIBezierPath bezierPath];  
  4.       
  5.     [path moveToPoint:CGPointMake(30200)];  
  6.     [path addQuadCurveToPoint:CGPointMake(10020) controlPoint:CGPointMake(1010)];  
  7.     UIColor * strokeColor = [UIColor redColor];  
  8.     [strokeColor set];  
  9.     [path stroke];  
  10. }  


画二次贝塞尔曲线的步骤:

  1. 先设置一个起始点,也就是通过-moveToPoint:设置
  2. 调用-addQuadCurveToPoint:controlPoint:方法设置终端点和控制点,以画二次曲线
这个样式看起来很像sin或者cos函数吧?这两个只是特例而已,其实可以画任意图形,只是想不到,没有做不到的。

画三次贝塞尔曲线

贝塞尔曲线必定通过首尾两个点,称为端点;中间两个点虽然未必要通过,但却起到牵制曲线形状路径的作用,称作控制点。关于三次贝塞尔曲线的控制器,看下图:


image

提示:其组成是起始端点+控制点1+控制点2+终止端点

如下方法就是画三次贝塞尔曲线的关键方法,以三个点画一段曲线,一般和-moveToPoint:配合使用。

- (void)addCurveToPoint:(CGPoint)endPoint           controlPoint1:(CGPoint)controlPoint1           controlPoint2:(CGPoint)controlPoint2

[objc] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. - (void)drawThirdBezierPath {  
  2.     UIBezierPath *path = [UIBezierPath bezierPath];  
  3.       
  4.     // 设置起始端点  
  5.     [path moveToPoint:CGPointMake(20150)];  
  6.       
  7.     [path addCurveToPoint:CGPointMake(300150)  
  8.             controlPoint1:CGPointMake(1600)  
  9.             controlPoint2:CGPointMake(160250)];  
  10.       
  11.     path.lineCapStyle = kCGLineCapRound;  
  12.     path.lineJoinStyle = kCGLineJoinRound;  
  13.     path.lineWidth = 5.0;  
  14.       
  15.     UIColor *strokeColor = [UIColor redColor];  
  16.     [strokeColor set];  
  17.       
  18.     [path stroke];  
  19. }  



我们需要注意,这里确定的起始端点为(20,150),终止端点为(300, 150),基水平方向是一致的。控制点1的坐标是(160,0),水平方向相当于在中间附近,这个参数可以调整。控制点2的坐标是(160,250),如果以两个端点的连线为水平线,那么就是250-150=100,也就是在水平线下100。这样看起来就像一个sin函数了。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 广工期末考试被老师警告了怎么办 我在农村不当队长我能力不够怎么办 我在农村不当队长我当代表怎么办 北京本地人社保中间断了一年怎么办 我想把大哥的孩子带出国要怎么办 美国有亲戚想让孩子出国怎么办 连接温控器的线断了怎么办 植发后好多原生发都脱落了怎么办 4岁宝宝支体能力差怎么办 当与游客发生矛盾时员工怎么办 顾客与同事发生矛盾你该怎么办 当一个人犯下的过错难以原谅怎么办 开车把别人撞成植物人了该怎么办 结婚证丢了孩子上不上学了怎么办 办房产证前加户主姓名怎么办手续 孩子上学户口跟房产不在一起怎么办 我家小孩被别的家长打了怎么办 要是小孩骗家长说老师打他怎么办 孩子在学校被家长打小孩怎么办 小孩在学校被老师打淤青家长怎么办 小孩和家长一吵架就说死怎么办 王者荣耀号被别人家长联接了怎么办 儿子12岁总是跟大人顶嘴怎么办 课堂上有学生和你顶嘴你怎么办 小孩看到大人吵架就哭了 怎么办 五年级的孩子叛逆爱发脾气怎么办 6个月孩子多动怎么办呀 小孩被大人打了很生气该怎么办 小孩在学校调皮被老师打了怎么办 四岁宝宝咳嗽半个月了怎么办 三岁宝宝咳嗽半个月了还不好怎么办 孩子在幼儿园不听话天天罚站怎么办 孩子个性太强脾气太倔不听话怎么办 孩子有十七了太不听话了怎么办 小孩的学籍填错了怎么办还能改吗 生完孩子后脾气暴躁易怒怎么办 生完孩子之后变懒了怎么办呀? 孩子三年级了成绩不突出家长怎么办 自私势力的父母想把我害死怎么办 父母如果养出自私的孩子怎么办 大人得了地图舌怎么办要怎么治疗