概述
在iOS系统中,所有显示在屏幕中的绘画,不管是通过 OpenGL
,Quartz
,UIKit
,还是Core Animation
,都是局限在 UIView
对象或者其子类的对象中。如果用的是系统定义的 UIView
,绘画过程是自动进行的。如果自定义 UIView
,那么我们自己定义绘画的代码。
除了直接绘画在屏幕上,UIKit框架还提供了屏幕外的 bitmap
和 PDF
图形上下文(graphics contexts)。如果是这类的,那么 view
的绘画循环是不适合这个情况的。
UIView 的绘图循环
当 UIView
需要第一次显示或者 view
的一部分需要重绘,UIView
的 drawRect:
方法会被调用进行重绘。
需要重绘的情况:
-
移动或者去除遮挡你的
view
的其它view
-
把
hidden
属性设为NO
让其他的隐藏的view
重新显示 -
把
view
滚动出屏幕,然后又重新进入屏幕 -
主动调用
setNeedsDisplay
或者setNeedsDisplayInRect
方法
UIKit 和 Core Graphics 两个框架都支持绘图:
Core Graphics
中涉及绘图的主要有 Graphics contexts,Paths,Images and bitmaps,Transparency layers,Colors,pattern colors,and color spacesGradients and shadings 等
UIKit 中涉及绘图的主要有 UIImage
,UIColor
,UIFont
, UIScreen
, UIBezierPath
等
Graphics contexts
要绘图必须有一个 graphics contexts
,这个对象可以理解成一个画布,所有的东西都要在这上面进行。drawRect:
、drawLayer: inContext:
、UIGraphicsBeginImageContextWithOptions
这个三个方法中都可以去获得 Graphic Context
从而绘制图形。
例如我们想画一个矩形,边框是蓝色的,宽度是20,填充红色

这样就存在 6 种绘图的方式:
方式一:在 UIView
的 drawRect:
方法中用 Core Graphics
框架实现
swift
override func draw(_ rect: CGRect) {
let ctx = UIGraphicsGetCurrentContext()
ctx?.setLineWidth(20)
ctx?.setStrokeColor(UIColor.blue.cgColor)
ctx?.setFillColor(UIColor.red.cgColor)
ctx?.addRect(CGRect(x: 0, y: 0, width: bounds.width, height: bounds.height))
ctx?.drawPath(using: .fillStroke)
}
oc
- (void)drawRect:(CGRect)rect {
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(ctx, 20);
CGContextSetRGBFillColor(ctx, 1, 0, 0, 1);
CGContextSetRGBStrokeColor(ctx, 0, 0, 1, 1);
CGContextAddRect(ctx, CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height));
CGContextDrawPath(ctx, kCGPathFillStroke);
}
方式二:在 UIView
的 drawRect:
方法中用 UIKit
框架实现
swift
override func draw(_ rect: CGRect) {
let path = UIBezierPath(rect: CGRect(x: 10, y: 10, width: bounds.width - 20, height: bounds.height - 20))
path.lineWidth = 20
UIColor.blue.setStroke()
UIColor.red.setFill()
path.stroke()
path.fill()
}
oc
- (void)drawRect:(CGRect)rect {
UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(10, 10, self.bounds.size.width - 20, self.bounds.size.height - 20)];
path.lineWidth = 20;
[[UIColor blueColor] setStroke];
[[UIColor redColor] setFill];
[path stroke];
[path fill];
}
方式三:在 CALayer
的代理方法 - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx;
中用 Core Graphics
框架实现
swift
import UIKit
class ViewController: UIViewController, CALayerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let myLayer = CALayer()
myLayer.frame = CGRect(x: 100, y: 100, width: 200, height: 200)
myLayer.delegate = self
view.layer.addSublayer(myLayer)
myLayer.setNeedsDisplay()
}
func draw(_ layer: CALayer, in ctx: CGContext) {
ctx.setLineWidth(20)
ctx.setStrokeColor(UIColor.blue.cgColor)
ctx.setFillColor(UIColor.red.cgColor)
ctx.addRect(CGRect(x: 0, y: 0, width: layer.bounds.width, height: layer.bounds.height))
ctx.drawPath(using: .fillStroke)
}
}
oc
#import "ViewController.h"
@interface ViewController () <CALayerDelegate>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
CALayer *myLayer = [CALayer layer];
myLayer.frame = CGRectMake(100, 100, 200, 200);
myLayer.delegate = self;
[self.view.layer addSublayer:myLayer];
[myLayer setNeedsDisplay];
}
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
CGContextSetLineWidth(ctx, 20);
CGContextSetRGBFillColor(ctx, 1, 0, 0, 1);
CGContextSetRGBStrokeColor(ctx, 0, 0, 1, 1);
CGContextAddRect(ctx, CGRectMake(0, 0, layer.bounds.size.width, layer.bounds.size.height));
CGContextDrawPath(ctx, kCGPathFillStroke);
}
@end
方式四:在 CALayer
的代理方法 - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx;
中用 UIKit
框架实现
swift
import UIKit
class ViewController: UIViewController, CALayerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let myLayer = CALayer()
myLayer.frame = CGRect(x: 100, y: 100, width: 200, height: 200)
myLayer.delegate = self
view.layer.addSublayer(myLayer)
myLayer.setNeedsDisplay()
}
func draw(_ layer: CALayer, in ctx: CGContext) {
UIGraphicsPushContext(ctx)
let path = UIBezierPath(rect: CGRect(x: 10, y: 10, width: layer.bounds.width - 20, height: layer.bounds.height - 20))
path.lineWidth = 20
UIColor.blue.setStroke()
UIColor.red.setFill()
path.stroke()
path.fill()
UIGraphicsPopContext()
}
}
oc
#import "ViewController.h"
@interface ViewController () <CALayerDelegate>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
CALayer *myLayer = [CALayer layer];
myLayer.frame = CGRectMake(100, 100, 200, 200);
myLayer.delegate = self;
[self.view.layer addSublayer:myLayer];
[myLayer setNeedsDisplay];
}
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
UIGraphicsPushContext(ctx);
UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(10, 10, layer.bounds.size.width - 20, layer.bounds.size.height - 20)];
path.lineWidth = 20;
[[UIColor blueColor] setStroke];
[[UIColor redColor] setFill];
[path stroke];
[path fill];
UIGraphicsPopContext();
}
@end
方式五:用 UIGraphicsBeginImageContextWithOptions
和 UIKit
框架实现
swift
UIGraphicsBeginImageContextWithOptions(CGSize(width: 200, height: 200), false, 0)
let path = UIBezierPath(rect: CGRect(x: 10, y: 10, width: 200 - 20, height: 200 - 20))
path.lineWidth = 20
UIColor.blue.setStroke()
UIColor.red.setFill()
path.stroke()
path.fill()
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
let imageView = UIImageView(frame: CGRect(x: 100, y: 100, width: 200, height: 200))
imageView.image = image
view.addSubview(imageView)
oc
UIGraphicsBeginImageContextWithOptions(CGSizeMake(200, 200), NO, 0);
UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, 200, 200)];
[path setLineWidth:20];
[[UIColor redColor] setFill];
[[UIColor blueColor] setStroke];
[path fill];
[path stroke];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];
imageView.image = image;
[self.view addSubview:imageView];
方式六:用 UIGraphicsBeginImageContextWithOptions
和 Core Graphics
框架实现
swift
UIGraphicsBeginImageContextWithOptions(CGSize(width: 200, height: 200), false, 0)
let ctx = UIGraphicsGetCurrentContext()
ctx?.setLineWidth(20)
ctx?.setStrokeColor(UIColor.blue.cgColor)
ctx?.setFillColor(UIColor.red.cgColor)
ctx?.addRect(CGRect(x: 0, y: 0, width: 200, height: 200))
ctx?.drawPath(using: .fillStroke)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
let imageView = UIImageView(frame: CGRect(x: 100, y: 100, width: 200, height: 200))
imageView.image = image
view.addSubview(imageView)
oc
UIGraphicsBeginImageContextWithOptions(CGSizeMake(200, 200), NO, 0);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(ctx, 20);
CGContextSetRGBFillColor(ctx, 1, 0, 0, 1);
CGContextSetRGBStrokeColor(ctx, 0, 0, 1, 1);
CGContextAddRect(ctx, CGRectMake(0, 0, 200, 200));
CGContextDrawPath(ctx, kCGPathFillStroke);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];
imageView.image = image;
[self.view addSubview:imageView];
画直线
我们可以通过 Core Graphics
和 UIKit
框架画直线
Core Graphics

- (void)drawRect:(CGRect)rect {
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(ctx, [UIColor redColor].CGColor);//设置线的颜色
CGContextSetLineWidth(ctx, 5);//设置线的宽度
CGContextSetLineCap(ctx, kCGLineCapRound);//设置线的起始端的样式
CGContextSetLineJoin(ctx, kCGLineJoinRound);//设置线的连接样式
//设置虚线
CGFloat length[] = {10 , 5, 10};
CGContextSetLineDash(ctx, 8, length, 3);
//画一条线
CGContextMoveToPoint(ctx, 10, 50);
CGContextAddLineToPoint(ctx, 100, 50);
//同时依次画多条线
CGPoint lines[] = {
CGPointMake(10.0, 90.0),
CGPointMake(70.0, 60.0),
CGPointMake(130.0, 90.0),
CGPointMake(190.0, 60.0),
CGPointMake(250.0, 90.0),
CGPointMake(310.0, 60.0),
};
//参数二:线数组,参数三:线的个数
CGContextAddLines(ctx, lines, sizeof(lines)/sizeof(lines[0]));
CGContextStrokePath(ctx);
}
UIKit

- (void)drawRect:(CGRect)rect {
UIBezierPath *path = [UIBezierPath bezierPath];
//设置虚线
CGFloat length[] = {10, 5, 10};
[path setLineDash:length count:3 phase:8];
[path moveToPoint:CGPointMake(10, 50)];
[path addLineToPoint:CGPointMake(100, 50)];
path.lineWidth = 2;
[[UIColor redColor] setStroke];
[path stroke];
path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(10.0, 90.0)];
[path addLineToPoint:CGPointMake(70.0, 60.0)];
[path addLineToPoint:CGPointMake(130.0, 90.0)];
[path addLineToPoint:CGPointMake(190.0, 60.0)];
[path addLineToPoint:CGPointMake(250.0, 90.0)];
[path addLineToPoint:CGPointMake(310.0, 60.0)];
path.lineWidth = 5;
[path stroke];
}
画弧线
CGContext
实现

- (void)drawRect:(CGRect)rect {
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetRGBStrokeColor(ctx, 1, 0, 0, 1);//设置线的颜色
CGContextSetRGBFillColor(ctx, 0, 0, 1, 1);//设置填充颜色
CGContextSetLineWidth(ctx, 2); //设置线的宽度
CGContextAddEllipseInRect(ctx, CGRectMake(10, 30, 60, 60)); //画一个椭圆或者圆
CGContextDrawPath(ctx, kCGPathFillStroke);
//根据中心点,半径,起始的弧度,最后的弧度,是否顺时针画一个圆弧
CGContextAddArc(ctx, 140, 60, 30, M_PI/2.f, M_PI, 1);
CGContextDrawPath(ctx, kCGPathStroke);
CGPoint p[3] =
{
CGPointMake(210.0, 30.0),
CGPointMake(210.0, 60.0),
CGPointMake(240.0, 60.0),
};
//先移到p1点
CGContextMoveToPoint(ctx, p[0].x, p[0].y);
//从p1点开始画弧线,圆弧和p1-p2相切;p2-p3和弧线相切,圆弧的半径是20
CGContextAddArcToPoint(ctx, p[1].x, p[1].y, p[2].x, p[2].y, 20.0);
CGContextStrokePath(ctx);
//画一个圆角矩形
CGRect rrect = CGRectMake(210.0, 70.0, 60.0, 60.0);
CGFloat radius = 10.0;
CGFloat minx = CGRectGetMinX(rrect), midx = CGRectGetMidX(rrect), maxx = CGRectGetMaxX(rrect);
CGFloat miny = CGRectGetMinY(rrect), midy = CGRectGetMidY(rrect), maxy = CGRectGetMaxY(rrect);
CGContextMoveToPoint(ctx, minx, midy);
CGContextAddArcToPoint(ctx, minx, miny, midx, miny, radius);
CGContextAddArcToPoint(ctx, maxx, miny, maxx, midy, radius);
CGContextAddArcToPoint(ctx, maxx, maxy, midx, maxy, radius);
CGContextAddArcToPoint(ctx, minx, maxy, minx, midy, radius);
CGContextClosePath(ctx);
CGContextDrawPath(ctx, kCGPathFillStroke);
//贝塞尔曲线一,两个控制点
CGPoint s = CGPointMake(30.0, 120.0); //起始点
CGPoint e = CGPointMake(300.0, 120.0);//终点
CGPoint cp1 = CGPointMake(120.0, 30.0);//控制点1
CGPoint cp2 = CGPointMake(210.0, 210.0);//控制点2
CGContextMoveToPoint(ctx, s.x, s.y);
CGContextAddCurveToPoint(ctx, cp1.x, cp1.y, cp2.x, cp2.y, e.x, e.y);
CGContextStrokePath(ctx);
//贝塞尔曲线二,一个控制点
s = CGPointMake(30.0, 300.0);
e = CGPointMake(270.0, 300.0);
cp1 = CGPointMake(150.0, 180.0);
CGContextMoveToPoint(ctx, s.x, s.y);
CGContextAddQuadCurveToPoint(ctx, cp1.x, cp1.y, e.x, e.y);
CGContextStrokePath(ctx);
}
UIKit
实现

- (void)drawRect:(CGRect)rect {
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(10, 30, 60, 60)];
[[UIColor redColor] setStroke];
[[UIColor blueColor] setFill];
path.lineWidth = 2;
[path stroke];
[path fill];
path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(140, 60) radius:30 startAngle:M_PI/2.f endAngle:M_PI clockwise:YES];
path.lineWidth = 2;
[path stroke];
path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(210, 70, 60, 60) cornerRadius:5];
path.lineWidth = 2;
[path stroke];
[path fill];
path = [UIBezierPath bezierPath];
path.lineWidth = 2;
CGPoint s = CGPointMake(30.0, 120.0);
CGPoint e = CGPointMake(300.0, 120.0);
CGPoint cp1 = CGPointMake(120.0, 30.0);
CGPoint cp2 = CGPointMake(210.0, 210.0);
[path moveToPoint:s];
[path addCurveToPoint:e controlPoint1:cp1 controlPoint2:cp2];
[path stroke];
path = [UIBezierPath bezierPath];
path.lineWidth = 2;
s = CGPointMake(30.0, 300.0);
e = CGPointMake(270.0, 300.0);
cp1 = CGPointMake(150.0, 180.0);
[path moveToPoint:s];
[path addQuadCurveToPoint:e controlPoint:cp1];
[path stroke];
}
绘制文字和图像
绘制图形和文字之前需要了解两个坐标系统。
Upper-left-origin coordinate system (ULO)
:左上为起始点的坐标系统,UIKit
、Core Animation
框架用的是这个坐标系统。
Lower-left-origin coordinate system (LLO)
:左下为起始点坐标系统,Core Graphics
框架是这个坐标系统。
这两个不同的坐标系统的不同,就必然需要 Core Graphics
绘制的图片需要上下翻转,才能正常在 UIView
中显示。 此外,UIImage
和 NSString
可以直接绘制,所以不需要像前面绘制圆弧,直线等一样去用 UIBezierPath
类去绘制了。
实现方法一:通过 UIView
的 drawInRect:
方法内用 UIKit
框架实现
[image drawInRect:CGRectMake(20, 20, 200, 200)];
[@"这是一段文字" drawAtPoint:CGPointMake(10, 120) withAttributes:@{NSFontAttributeName: [UIFont systemFontOfSize:14], NSForegroundColorAttributeName: [UIColor blackColor]}];
图片操作
/// 调整图片大小
func resizeImage(image: UIImage, toSize: CGSize) -> UIImage {
if UIScreen.main.scale == 2.0 {
UIGraphicsBeginImageContextWithOptions(toSize, false, 2.0)
} else if UIScreen.main.scale == 3.0 {
UIGraphicsBeginImageContextWithOptions(toSize, false, 3.0)
} else {
UIGraphicsBeginImageContext(toSize)
}
image.draw(in: CGRect(x: 0, y: 0, width: toSize.width, height: toSize.height))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!
}
/// 比例缩放图片
func scaleImage(image: UIImage, toScale: CGFloat) -> UIImage {
if UIScreen.main.scale == 2.0 {
UIGraphicsBeginImageContextWithOptions(CGSize(width: image.size.width * toScale, height: image.size.height * toScale), false, 2.0)
} else if UIScreen.main.scale == 3.0 {
UIGraphicsBeginImageContextWithOptions(CGSize(width: image.size.width * toScale, height: image.size.height * toScale), false, 3.0)
} else {
UIGraphicsBeginImageContext(CGSize(width: image.size.width * toScale, height: image.size.height * toScale))
}
image.draw(in: CGRect(x: 0, y: 0, width: image.size.width * toScale, height: image.size.height * toScale))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!
}
实现方法二:通过 UIView
的 drawInRect:
方法内用 Core Graphics
框架实现
- (void)drawRect:(CGRect)rect {
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSaveGState(ctx);
//翻转起来---上下颠倒
CGContextTranslateCTM(ctx, 0.0, self.bounds.size.height);
CGContextScaleCTM(ctx, 1.0, -1.0);
//假设想在 (10, 20, 80, 100) 的地方绘制,颠倒过来后的 Rect 应该是 (10, self.bounds.size.height - (100 + 20), 80, 80)
CGRect imageRect = CGRectMake(10, self.bounds.size.height - (100 + 20), 80, 100);
CGContextDrawImage(ctx, imageRect, [UIImage imageNamed:@"image.jpeg"].CGImage);
CGContextRestoreGState(ctx);
}
方法三:通过 UIGraphicsBeginImageContextWithOptions
方便的创建图片
UIGraphicsBeginImageContext(CGSizeMake(80, 100));
[[UIImage imageNamed:@"image.jpeg"] drawInRect: CGRectMake(0, 0, 80, 80)];
[@"这是一段文字" drawAtPoint: CGPointMake(0, 50) withAttributes:@{NSFontAttributeName: [UIFont systemFontOfSize:14], NSForegroundColorAttributeName: [UIColor blackColor]}];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
绘制渐变
iOS Core Graphics
的渐变可以分成径向渐变和辐射渐变。可以实现如下的图形:
可以在 view
的 - (void)drawRect:(CGRect)rect
实现

- (void)drawRect:(CGRect)rect {
CGContextRef ctx = UIGraphicsGetCurrentContext();
//创建一个RGB的颜色空间
CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
//定义渐变颜色数组
CGFloat colors[] =
{
204.0 / 255.0, 224.0 / 255.0, 244.0 / 255.0, 1.00,
29.0 / 255.0, 156.0 / 255.0, 215.0 / 255.0, 1.00,
0.0 / 255.0, 50.0 / 255.0, 126.0 / 255.0, 1.00,
};
//创建一个渐变的色值 1:颜色空间 2:渐变的色数组 3:位置数组,如果为NULL,则为平均渐变,否则颜色和位置一一对应 4:位置的个数
CGGradientRef _gradient = CGGradientCreateWithColorComponents(rgb, colors, NULL, sizeof(colors)/(sizeof(colors[0])*4));
CGColorSpaceRelease(rgb);
//获得一个CGRect
CGRect clip = CGRectInset(CGContextGetClipBoundingBox(ctx), 20.0, 20.0);
//剪切到合适的大小
CGContextClipToRect(ctx, clip);
//定义起始点和终止点
CGPoint start = CGPointMake(20, 20);
CGPoint end = CGPointMake(20, 100);
//绘制渐变, 颜色的0对应start点,颜色的1对应end点,第四个参数是定义渐变是否超越起始点和终止点
CGContextDrawLinearGradient(ctx, _gradient, start, end, kCGGradientDrawsBeforeStartLocation);
//辐射渐变
start = CGPointMake(100, 80);//起始点
end = CGPointMake(100, 140); //终结点
//辐射渐变 start:起始点 20:起始点的半径 end:终止点 40: 终止点的半径 这个辐射渐变
CGContextDrawRadialGradient(ctx, _gradient, start, 20, end, 40, 0);
}
UIKit
提供一个 CALayer
的子类,专门绘制渐变,但是只支持线性渐变

CAGradientLayer *gradient = [CAGradientLayer layer];//创建渐变层
gradient.frame = CGRectMake(100, 100, 200, 200);
[self.view.layer addSublayer:gradient];
//渐变层的颜色梯度数组
gradient.colors = @[(__bridge id)[UIColor colorWithRed:204.0 / 255.0 green:224.0 / 255.0 blue:244.0 / 255.0 alpha:1].CGColor,
(__bridge id)[UIColor colorWithRed:29.0 / 255.0 green:156.0 / 255.0 blue:215.0 / 255.0 alpha:1].CGColor,
(__bridge id)[UIColor colorWithRed:0.0 / 255.0 green:50.0 / 255.0 blue:126.0 / 255.0 alpha:1].CGColor];
//渐变层的相对位置,起始点为0,终止点为1,中间点为 (point-startpoint)/(endpoint-startpoint)
gradient.locations = @[@0,@.5,@1];
//渐变方向
gradient.startPoint = CGPointMake(0, 0);
gradient.endPoint = CGPointMake(0, 1);
利用 CAShapeLayer、UIBezierPath、CGPath 绘制图像
iOS 提供了一个 CALayer
类,专门负责负责绘制 CGPath
显示内容。最方便的方法是利用 UIBezierPath
绘制的 CGPath
,或者直接创建的 CGPath
进行图形的绘制。
例如我们想根据圆弧标示进展。那么我们如何绘制呢

1. CAShapeLayer
和 UIBezierPath
的组合:
for (int i = 0; i < 4; i ++) {
CAShapeLayer *layerOne = [CAShapeLayer layer];
layerOne.frame = CGRectMake(50 + 80 * i, 100, 60, 60);
UIBezierPath *circlePath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 60, 60)];
layerOne.path = circlePath.CGPath;
//只是借用Path,不能借用图形设置,必须设置在layer中哦
layerOne.fillColor = [UIColor whiteColor].CGColor;
layerOne.lineWidth = 2;
layerOne.strokeColor = [UIColor blueColor].CGColor;
[self.view.layer addSublayer:layerOne];
CAShapeLayer *layerTwo = [CAShapeLayer layer];
CGRect frame = layerOne.frame;
frame.origin.x += 4;
frame.origin.y += 4;
frame.size.width -= 8;
frame.size.height -= 8;
layerTwo.frame = frame;
UIBezierPath *innerpath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(26, 26) radius:frame.size.width/2 startAngle:0 endAngle:M_PI*(i+1)/3.f clockwise:YES];
[innerpath addLineToPoint:CGPointMake(26, 26)];
[innerpath closePath];
layerTwo.path = innerpath.CGPath;
layerTwo.fillColor = [UIColor blueColor].CGColor;
[self.view.layer addSublayer:layerTwo];
}
2. CAShapeLayer
和 CGPath
的组合:
for (int i = 0; i < 4; i ++) {
CAShapeLayer *layerOne = [CAShapeLayer layer];
layerOne.frame = CGRectMake(50 + 80 * i, 100, 60, 60);
CGMutablePathRef circlePath = CGPathCreateMutable();
CGPathAddEllipseInRect(circlePath, NULL, CGRectMake(0, 0, 60, 60));
layerOne.path = circlePath;
layerOne.fillColor = [UIColor whiteColor].CGColor;
layerOne.lineWidth = 2;
layerOne.strokeColor = [UIColor blueColor].CGColor;
CGPathRelease(circlePath);
[self.view.layer addSublayer:layerOne];
CAShapeLayer *layerTwo = [CAShapeLayer layer];
CGRect frame = layerOne.frame;
frame.origin.x += 4;
frame.origin.y += 4;
frame.size.width -= 8;
frame.size.height -= 8;
layerTwo.frame = frame;
CGMutablePathRef innerPath = CGPathCreateMutable();
CGPathAddArc(innerPath, NULL, 26, 26, frame.size.width/2, 0, M_PI*(i+1)/3.f, NO);
CGPathAddLineToPoint(innerPath, NULL, 26, 26);
CGPathCloseSubpath(innerPath);
layerTwo.path = innerPath;
layerTwo.fillColor = [UIColor blueColor].CGColor;
[self.view.layer addSublayer:layerTwo];
}
网友评论