iOS中绘图
Posted Jk_Chan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS中绘图相关的知识,希望对你有一定的参考价值。
UIBezierPath:可以创建基于矢量的路径,是Core Graphics框架关于path的一个封装,可以定义简单的形状,如椭圆或者矩形,或者有多个直线和曲线段组成的形状。
实例化方法:
1、根据一个矩形画曲线
+ (UIBezierPath *)bezierPathWithRect:(CGRect)rect
2、根据矩形框的内切圆画曲线
+ (UIBezierPath *)bezierPathWithOvalInRect:(CGRect)rect
3、根据矩形画带圆角的曲线
+ (UIBezierPath *)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius
4、在矩形中,可以针对四角中的某个角加圆角, 一般用于设置某个视图的顶端两角为圆形
+ (UIBezierPath *)bezierPathWithRoundedRect:(CGRect)rect byRoundingCorners:(UIRectCorner)corners cornerRadii:(CGSize)cornerRadii
参数:
corners:枚举值,可以选择某个角
cornerRadii:圆角的大小
5、以某个中心点画弧线
+ (UIBezierPath *)bezierPathWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise;
参数:
center:弧线中心点的坐标
radius:弧线所在圆的半径
startAngle:弧线开始的角度值
endAngle:弧线结束的角度值
clockwise:是否顺时针画弧线
6、自定义路径
+ (UIBezierPath *)bezierPath
画二元曲线,一般和moveToPoint方法配合使用
- (void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint
参数:
endPoint:曲线的终点
controlPoint:画曲线的基准点
以三个点画一段曲线,一般和moveToPoint方法配合使用
- (void)addCurveToPoint:(CGPoint)endPoint controlPoint1:(CGPoint)controlPoint1 controlPoint2:(CGPoint)controlPoint2
参数:
endPoint:曲线的终点
controlPoint1:画曲线的第一个基准点
controlPoint2:画曲线的第二个基准点
对象常用方法:
[myPath setLineWidth:1];
[myPath stroke];
[myPath fill];
在UIView类或继承UIView的子类的drawRect:方法中编写绘图工作
使用范例:
[[UIColor blueColor]setStroke];//设置画笔颜色
[[UIColor redColor]setFill];//设置填充颜色
UIBezierPath *path=[UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(100, 30)];
[path addLineToPoint:CGPointMake(50, 70)];
[path addLineToPoint:CGPointMake(150, 70)];
[path closePath];//最后一条闭合图形线由closePath方法创建
[path setLineWidth:3];//设置画笔宽度
[path stroke];//画path
[path fill];//填充颜色
path=[UIBezierPath bezierPathWithRect:CGRectMake(50, 200, 50, 50)];
[path stroke];
path=[UIBezierPath bezierPathWithOvalInRect:CGRectMake(100, 200, 50, 50)];
[path stroke];
path=[UIBezierPath bezierPathWithRoundedRect:CGRectMake(150, 200, 50, 50) cornerRadius:10];
[path stroke];
path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(200, 200, 50, 50) byRoundingCorners:(UIRectCornerTopLeft |UIRectCornerTopRight) cornerRadii:CGSizeMake(10, 10)];
[path stroke];
path=[UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(20, 300)];
[path addQuadCurveToPoint:CGPointMake(300, 300) controlPoint:CGPointMake(180, 400)];
[path stroke];
path=[UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(20, 400)];
[path addCurveToPoint:CGPointMake(300, 400) controlPoint1:CGPointMake(120, 280) controlPoint2:CGPointMake(220, 480)];
[path stroke];
Core Graphics Framework:(可以用于基于路径的绘图、变换、颜色管理、脱屏渲染,模板、渐变、遮蔽、图像数据管理、图像的创建、遮罩以及PDF文档的创建、显示和分析。)
图形上下文CGContextRef:(可理解为画布)
需要获取图形上下文的两种方法:
1.创建一个图片类型的上下文:(在想生成图形的位置编写)
调用UIGraphicsBeginImageContextWithOptions(CGSize所要创建的图片尺寸,BOOL所生成图片背景是否为不透明,CGFloat生成的图片缩放因子一般传入0表示根据屏幕分辨率而变化)函数
利用该上下文,在其上进行绘图,调用UIGraphicsGetImageFromCurrentImageContext函数生成UIImage对象
然后需要调用UIGraphicsEndImageContext函数关闭图形上下文。
使用范例1(简单绘图):
//调用UIGraphicsBeginImageContextWithOptions绘图/*可以捕捉屏幕界面UIView,但是使用UIView * snap = [toView snapshotViewAfterScreenUpdates:YES];获取屏幕快照,比bitmap视图绘制画布获取画面方便*/
//使用UIKit在Cocoa为我们提供的当前上下文中完成绘图任务
UIGraphicsBeginImageContextWithOptions(CGSizeMake(50, 100), NO, 0);
UIBezierPath* p = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0,0,50,100)];
[[UIColor blueColor] setFill];
[p fill];
UIImage *myUIKitImage=UIGraphicsGetImageFromCurrentImageContext();
myImageView.image=myUIKitImage;
UIGraphicsEndImageContext();
//使用Core Graphics实现绘图(需自己获取图形上下文)
UIGraphicsBeginImageContextWithOptions(CGSizeMake(50,100), NO, 0);
CGContextRef context = UIGraphicsGetCurrentContext();//
CGContextAddEllipseInRect(context, CGRectMake(0,0,50,100));
CGContextSetFillColorWithColor(context, [UIColor purpleColor].CGColor);
CGContextFillPath(context);
UIImage* myCoreGraphicsImage = UIGraphicsGetImageFromCurrentImageContext();
myImageView2.layer.contents=(__bridge id)myCoreGraphicsImage.CGImage;
UIGraphicsEndImageContext();
使用范例2(以图片做基础平移绘图):
UIImage* myLocationImage = [UIImage imageNamed:@"boy2.png"];
CGSize sz = [myLocationImage size];
UIGraphicsBeginImageContextWithOptions(CGSizeMake(sz.width*2, sz.height*2), NO, 0);
[myLocationImage drawAtPoint:CGPointMake(0,0)];
[myLocationImage drawAtPoint:CGPointMake(sz.width,0)];
[myLocationImage drawAtPoint:CGPointMake(0,sz.height)];
[myLocationImage drawAtPoint:CGPointMake(sz.width,sz.height)];
UIImage* myImage = UIGraphicsGetImageFromCurrentImageContext();
UIImageView *myImageView3=[[UIImageView alloc]initWithImage:myImage];
myImageView3.center=self.center;
[self.view addSubview:myImageView3];
UIGraphicsEndImageContext();
使用范例3(以图片做基础缩放绘图):
UIImage* myLocationImage2 = [UIImage imageNamed:@"boy2.png"];
CGSize sz2 = [myLocationImage2 size];
UIGraphicsBeginImageContextWithOptions(CGSizeMake(sz2.width*2, sz2.height*2), NO, 0);
[myLocationImage2 drawInRect:CGRectMake(0,0,sz2.width*2,sz.height*2)];
[myLocationImage2 drawInRect:CGRectMake(sz2.width/2.0, sz2.height/2.0, sz2.width, sz2.height) blendMode:kCGBlendModeMultiply alpha:1.0];
UIImage* myImage2 = UIGraphicsGetImageFromCurrentImageContext();
UIImageView *myImageView4=[[UIImageView alloc]initWithImage:myImage2];
myImageView4.center=CGPointMake(self.center.x, self.center.y+200);
[self addSubview:myImageView4];
UIGraphicsEndImageContext();
应用范例4(以图片做基础裁切绘图)
UIImage *myLocationImage3=[UIImage imageNamed:@"boy2.png"];
CGSize sz3=[myLocationImage3 size];
UIGraphicsBeginImageContextWithOptions(CGSizeMake(sz3.width/2, sz3.height), NO, 0);
[myLocationImage3 drawAtPoint:CGPointMake(0, 0)];
UIImage *myImage3=UIGraphicsGetImageFromCurrentImageContext();
UIImageView *myImageView5=[[UIImageView alloc]initWithImage:myImage3];
myImageView5.center=CGPointMake(self.center.x, self.center.y-200);
[self addSubview:myImageView5];
UIGraphicsEndImageContext();
2.在UIView类或子类中实现drawRect:方法,当类初始化时该方法被调用,cocoa会生成图形上下文,此时对图形上下文的所有绘图操作都会显示在UIView上(在drawRect:方法中实现绘制)
使用范例:
//使用UIKit在Cocoa为我们提供的当前上下文中完成绘图任务
UIBezierPath* p = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0,0,50,100)];
[[UIColor blueColor] setFill];
[p fill];
//使用Core Graphics实现绘图
CGContextRef context=UIGraphicsGetCurrentContext();//
CGContextAddEllipseInRect(context, CGRectMake(30, 0, 50, 100));
CGContextSetFillColorWithColor(context, [UIColor purpleColor].CGColor);
CGContextFillPath(context);
····这两种方法都没有context:参数能直接拿到一个图形上下文引用,因而需要自己调用UIGraphicsGetCurrentContext函数获取当前图形上下文
自带图形上下文引用的一种方法:
drawRect:inContext:;其中context:参数即为图形上下文引用
当前图形上下文:
1.调用UIGraphicsBeginImageContextWithOptions函数后,该图形上下文属于当前上下文
2.当drawRect方法被调用时,UIView的绘图上下文属于当前图形上下文
3.回调方法所持有的context:参数不会让该上下文成为当前图形上下文,此参数仅是对一个图形上下文的引用,但相当于也拿到了一个图形上下文
4.调用UIGraphicsPushContext函数可以将context:参数转化为当前上下文;最后需要调用UIGraphicsPopContext函数恢复上下文环境
图形上下文属性设置:
图形上下文提供维持状态的栈
CGContextSaveGState(CGContextRef context)函数会将完整的当前上下文属性状态压入栈顶
CGContextRestoreGState(CGContextRef context)函数会取出栈顶的上下文属性状态设置为当前上下文属性状态
注意:CGContextSaveGState(CGContextRef context)函数和CGContextRestoreGState(CGContextRef context)函数必须成对出现,否则绘图很可能出现意想不到的错误
图形上下文属性包括:
1.线条的宽度和线条的虚线样式
CGContextSetLineWidth、CGContextSetLineDash
2.线帽和线条联接点样式
CGContextSetLineCap、CGContextSetLineJoin、CGContextSetMiterLimit
3.线条颜色和线条模式
CGContextSetRGBStrokeColor、CGContextSetGrayStrokeColor、CGContextSetStrokeColorWithColor、CGContextSetStrokePattern
4.填充颜色和模式
CGContextSetRGBFillColor,CGContextSetGrayFillColor,CGContextSetFillColorWithColor, CGContextSetFillPattern
5.阴影
CGContextSetShadow、CGContextSetShadowWithColor
6.混合模式
CGContextSetBlendMode(决定你当前绘制的图形与已经存在的图形如何被合成)
7.整体透明度
CGContextSetAlpha(个别颜色也具有alpha成分)
8.文本属性
CGContextSelectFont、CGContextSetFont、CGContextSetFontSize、CGContextSetTextDrawingMode、CGContextSetCharacterSpacing
9.是否开启反锯齿和字体平滑
CGContextSetShouldAntialias、CGContextSetShouldSmoothFonts
路径描画:一段路径是由点到点的描画构成,每一段新增的路径开始于当前点,当完成一条路径的描画,路径的终点就变成了当前点。
画线规定:
奇数像素宽度的线在渲染的时候将会表现为柔和的宽度扩展到向上的整数宽度的线,除非你手动的调整线的位置,使线刚好落在一行或列的显示单元内。
1 Point的线在非Retina屏幕则是一个像素,在Retina屏幕上则可能是2个或者3个
直接根据当前屏幕的缩放因子计算出1 像素线对应的Point,然后设置线宽,如果要画一条黑线,条线刚好落在了一列或者一行显示显示单元(像素)之内,将会渲染出标准的一个像素的黑线。
但如果线落在了两个行或列的中间时,那么会得到一条“失真”的线,其实是两个像素宽的灰线。
如何让线刚好落在一行或一列的显示单元上:
在非高清屏上,一个Point对应一个像素。为了防止“antialiasing”导致的奇数像素的线渲染时出现失真,你需要设置偏移0.5 Point。
在高清屏幕上,要绘制一个像素的线,需要设置线宽为0.5个Point,同事设置偏移为0.25 Point。
如果线宽为偶数Point的话,则不要去设置偏移,否则线条也会失真。
代码范例:
画线:
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(100 - ((1/[UIScreen mainScreen].scale)/2), 35, (1/[UIScreen mainScreen].scale), 330)];
画矩形:
UIView *view3=[[UIView alloc]initWithFrame:CGRectMake(110,150,100, 100)];
view3.backgroundColor=[UIColor clearColor];//填充色是透明的
view3.layer.borderColor=[UIColor redColor].CGColor;//边框的颜色:红色
view3.layer.borderWidth=1/[UIScreen mainScreen].scale;//边框的尺寸
[self addSubview:view3];
部分命令如下:
1.定位当前点
CGContextMoveToPoint
2.描画一条线
CGContextAddLineToPoint、CGContextAddLines
3.描画一个矩形
CGContextAddRect、CGContextAddRects
4.描画一个椭圆或圆形
CGContextAddEllipseInRect
5.描画一段圆弧
CGContextAddArcToPoint、CGContextAddArc
6.通过一到两个控制点描画一段贝赛尔曲线
CGContextAddQuadCurveToPoint、CGContextAddCurveToPoint
7.关闭当前路径
CGContextClosePath 这将从路径的终点到起点追加一条线。如果你打算填充一段路径,那么就不需要使用该命令,因为该命令会被自动调用。
8.描边或填充当前路径
CGContextStrokePath、CGContextFillPath、CGContextEOFillPath、CGContextDrawPath。(对当前路径描边或填充会清除掉路径。如果只想使用一条命令完成描边和填充任务,可以使用CGContextDrawPath命令,如果使用CGContextStrokePath对路径描边,路径就会被清除掉,就不能再对它进行填充了。)
9.创建路径并描边路径或填充路径只需一条命令就可完成的函数
CGContextStrokeLineSegments、CGContextStrokeRect、CGContextStrokeRectWithWidth、CGContextFillRect、CGContextFillRects、CGContextStrokeEllipseInRect、CGContextFillEllipseInRect。
10.指定绘制的路径是一条独立的路径
CGContextBeginPath
11.擦除一个矩形区域,矩形内的所有已存在的绘图;并对该区域执行裁剪。结果像是打了一个贯穿所有已存在绘图的孔,该孔是否透明取决于视图背景颜色是否为nil或有一点点的透明
CGContextClearRect
使用范例:
CGContextRef con = UIGraphicsGetCurrentContext();
// 绘制一个黑色的垂直黑色线,作为箭头的杆子
CGContextMoveToPoint(con, 100, 100);
CGContextAddLineToPoint(con, 100, 19);
CGContextSetLineWidth(con, 20);
CGContextStrokePath(con);
// 绘制一个红色三角形箭头
CGContextSetFillColorWithColor(con, [[UIColor redColor] CGColor]);
CGContextMoveToPoint(con, 80, 25);
CGContextAddLineToPoint(con, 100, 0);
CGContextAddLineToPoint(con, 120, 25);
CGContextFillPath(con);
// 从箭头杆子上裁掉一个三角形,使用清除混合模式(注意该视图的背景色)
CGContextMoveToPoint(con, 90, 101);
CGContextAddLineToPoint(con, 100, 90);
CGContextAddLineToPoint(con, 110, 101);
CGContextSetBlendMode(con, kCGBlendModeClear);
CGContextFillPath(con);
渐变:
简单的渐变由一端点的颜色与另一端点的颜色决定,如果在中间点加入颜色(可选),那么渐变会在上下文的两个点之间线性的绘制或在上下文的两个圆之间放射状的绘制。不能使用渐变作为路径的填充色,但可使用裁剪限制对路径形状的渐变
使用范例:在drawRect:方法中调用
CGContextRef con = UIGraphicsGetCurrentContext();
[self _drawGradientColor:con rect:CGRectMake(50, 50, 100, 100) options:kCGGradientDrawsBeforeStartLocation colors:@[[UIColor redColor],[UIColor blackColor],[UIColor blueColor],[UIColor grayColor]]];
-(void)_drawGradientColor:(CGContextRef)p_context rect:(CGRect)p_clipRect options:(CGGradientDrawingOptions)p_options colors:(NSArray *)p_colors {
CGContextSaveGState(p_context);// 保持住现在的context
CGContextClipToRect(p_context, p_clipRect);// 截取对应的context
int colorCount = p_colors.count;
int numOfComponents = 4;
CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
CGFloat colorComponents[colorCount * numOfComponents];
for (int i = 0; i < colorCount; i++) {
UIColor *color = p_colors[i];
CGColorRef temcolorRef = color.CGColor;
const CGFloat *components = CGColorGetComponents(temcolorRef);
for (int j = 0; j < numOfComponents; ++j) {
colorComponents[i * numOfComponents + j] = components[j];
}
}
CGGradientRef gradient = CGGradientCreateWithColorComponents(rgb, colorComponents, NULL, colorCount);
CGColorSpaceRelease(rgb);
CGPoint startPoint = p_clipRect.origin;
CGPoint endPoint = CGPointMake(CGRectGetMinX(p_clipRect), CGRectGetMaxY(p_clipRect));
CGContextDrawLinearGradient(p_context, gradient, startPoint, endPoint, p_options);
CGGradientRelease(gradient);
CGContextRestoreGState(p_context);// 恢复到之前的context
}
UIKit的UIBezierPath类:(通过类初始化方法可以快捷获取某些图形路径)
使用范例:
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(ctx, [UIColor blackColor].CGColor);
CGContextSetLineWidth(ctx, 1);
UIBezierPath *path;
path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(100, 100, 100, 100) byRoundingCorners:(UIRectCornerTopLeft |UIRectCornerTopRight) cornerRadii:CGSizeMake(10, 10)];
[path stroke];
UIImage与CGImage:
CGImage具体类型为CGImageRef
两者之间类型转换:
CGImageRef myCGImage=[UIImage imageNamed:@"boy2.png"].CGImage;//UIImage转CGImage
UIImage *myUIImage1=[[UIImage alloc]initWithCGImage:myCGImage];//CGImage转UIImage
UIImage *myUIImage2=[UIImage imageWithCGImage:myCGImage];//CGImage转UIImage
两者之间的区别:CGImage对象可以获取原始图片中指定区域的图片,也可以获取指定区域外的图片,UIImage却办不到
获取UIImage中指定区域的CGImage:
CGSize sz4=[myLocationImage4 size];
CGImageRef marsLeft = CGImageCreateWithImageInRect([myLocationImage4 CGImage],CGRectMake(0,0,sz4.width/2.0,sz4.height));
注意:使用CGImageCreateWithImageInRect()函数获取的CGImageRef对象使用CGContextDrawImage方法后从图像上下文中获取到的UIImage相对原来UIImage对应的区域图像是上下颠倒的,因为两者的相对坐标系不一样,
解决方法:使用CGContextDrawImage方法先将CGImage绘制到UIImage上,然后获取UIImage对应的CGImage,此时就得到了一个倒转的CGImage,当再对该倒转的CGImage使用CGContextDrawImage方法后从图像上下文中获取到的UIImage就不上下颠倒了
使用范例:
// 抽取图片的左右半边
UIImage *myLocationImage4=[UIImage imageNamed:@"boy2.png"];
CGImageRef myLocationImage4CGImageRef=[myLocationImage4 CGImage];//要先获取原始适配了分辨率后的图片的CGImageRef
CGSize sz4 = CGSizeMake(CGImageGetWidth(myLocationImage4CGImageRef), CGImageGetHeight(myLocationImage4CGImageRef));//大小也是要从适配了分辨率后的Image的CGImage的大小,不能是CGSize sz4=[myLocationImage4 size];
CGImageRef marsLeft = CGImageCreateWithImageInRect([myLocationImage4 CGImage],CGRectMake(0,0,sz4.width/2.0,sz4.height));
CGImageRef marsRight = CGImageCreateWithImageInRect([myLocationImage4 CGImage],CGRectMake(sz4.width/2.0,0,sz4.width/2.0,sz4.height));
// 将每一个CGImage绘制到图形上下文中
UIGraphicsBeginImageContextWithOptions(CGSizeMake(sz4.width*1.5, sz4.height), NO, 0);
CGContextRef context2 = UIGraphicsGetCurrentContext();
CGContextDrawImage(context2, CGRectMake(0,0,sz4.width/2.0,sz4.height), flip(marsLeft));
CGContextDrawImage(context2, CGRectMake(sz4.width,0,sz4.width/2.0,sz4.height), flip(marsRight));
UIImage* myImage4 = UIGraphicsGetImageFromCurrentImageContext();
UIImageView *myImageView6=[[UIImageView alloc]initWithImage:myImage4];
myImageView6.center=CGPointMake(self.center.x, self.center.y-220);
[self addSubview:myImageView6];
UIGraphicsEndImageContext();
// 记得释放内存,ARC在这里无效
CGImageRelease(marsLeft);
CGImageRelease(marsRight);
CGImageRef flip (CGImageRef im) {
CGSize sz = CGSizeMake(CGImageGetWidth(im), CGImageGetHeight(im)); UIGraphicsBeginImageContextWithOptions(sz, NO, 0);
CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, sz.width, sz.height), im);
CGImageRef result = [UIGraphicsGetImageFromCurrentImageContext() CGImage];
UIGraphicsEndImageContext();
return result;
}
CIFilter与CIImage:
CI表示CoreImage,一种使用数学滤镜变换图片的技术
CIFilter类:即滤镜
滤镜分类如下:
1.模板与渐变类
这两类滤镜创建的CIImage可以和其他的CIImage进行合并,比如一种单色,一个棋盘,条纹,亦或是渐变。
2.合成类
此类滤镜可以将一张图片与另外的图片合并
3.色彩类
此滤镜调整、修改图片的色彩。可以改变一张图片的饱和度、色度、亮度、对比度、伽马、白点、曝光度、阴影、高亮等属性。
4.几何变换类
此类滤镜可对图片执行基本的几何变换,比如缩放、旋转、裁剪。
CoreGraphics+CAAnimation实现按轨迹运动动画范例:
//拿到运动轨迹图
-(void)drawACurvedLine {
//创建一个图片画布,等下从它拿图
UIGraphicsBeginImageContext(CGSizeMake(320,460));
CGContextRef ctx = UIGraphicsGetCurrentContext();
//为绘图设置属性
CGContextSetLineWidth(ctx, 1);
CGContextSetStrokeColorWithColor(ctx, [UIColor whiteColor].CGColor);
//设置开始点
CGContextMoveToPoint(ctx, 10, 10);
//描绘一条贝塞尔曲线
CGContextAddQuadCurveToPoint(ctx, 10, 450, 310, 450);
//再描绘一条贝塞尔曲线与第一条形成闭合
CGContextAddQuadCurveToPoint(ctx, 310, 10, 10, 10);
//画出这两条线
CGContextDrawPath(ctx, kCGPathStroke);
//从画布中取出图片
UIImage *curve = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *curveView = [[UIImageView alloc] initWithImage:curve];
curveView.frame = CGRectMake(1, 1, 320, 460);
curveView.backgroundColor = [UIColor clearColor];
[self addSubview:curveView];
}
//创建关键帧动画(使UIView运动是针对该UIView的layer层添加动画而实现)
-(void)animateCicleAlongPath {
//准备关键帧动画
CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
//设置关键帧动画属性
pathAnimation.calculationMode = kCAAnimationPaced;
pathAnimation.fillMode = kCAFillModeForwards;
pathAnimation.removedOnCompletion = NO;
pathAnimation.duration = 3.0;
pathAnimation.repeatCount = 1000;
//设置动画路径
CGMutablePathRef curvedPath = CGPathCreateMutable();//创建一个可变路径集
CGPathMoveToPoint(curvedPath, NULL, 10, 10);//设置可变路径集起点
CGPathAddQuadCurveToPoint(curvedPath, NULL, 10, 450, 310, 450);//在可变路劲集中添加贝塞尔曲线
CGPathAddQuadCurveToPoint(curvedPath, NULL, 310, 10, 10, 10);//在可变路劲集中添加贝塞尔曲线
//设置关键帧动画运动路径为上面的路径集
pathAnimation.path = curvedPath;
CGPathRelease(curvedPath);//释放路径集
//创建一个图片画布,等下从它拿图
UIGraphicsBeginImageContext(CGSizeMake(20,20));
CGContextRef ctx = UIGraphicsGetCurrentContext();
//为绘图设置属性
CGContextSetLineWidth(ctx, 1.0);//设置线宽
CGContextSetFillColorWithColor(ctx, [UIColor greenColor].CGColor);//设置填充颜色
CGContextSetStrokeColorWithColor(ctx, [UIColor whiteColor].CGColor);//设置线条颜色
//描绘一个圆形
CGContextAddEllipseInRect(ctx, CGRectMake(1, 1, 18, 18));
//在画布上画出该描绘图案
CGContextDrawPath(ctx, kCGPathFillStroke);
//取出画图案
UIImage *circle = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *circleView = [[UIImageView alloc] initWithImage:circle];
circleView.frame = CGRectMake(1, 1, 20, 20);
[self addSubview:circleView];
//为该UIImageView添加上面设置好路径运动的关键帧动画,添加后该动画便开始执行
[circleView.layer addAnimation:pathAnimation forKey:@"moveTheSquare"];
}
以上是关于iOS中绘图的主要内容,如果未能解决你的问题,请参考以下文章