Quartz2D
-
Quartz2D是苹果封装的一个库,针对iOS和os系统绘制不同的类型的制图方式
-
图形上下文(一种数据类型,类似int,double)数据类型(
CGContextRef
) -
不同的
上下文
(数据类型)可以绘制不同的类型(pdf
,bitmap
,layer
,window
,ptinter
) -
进而上面5中类型,对应不同的
上下文
1. 绘制简单图形 -> 画线
- 在自定义的
View
我们可以通知drawRect:
方法绘制,自己想要的线条 - 苹果内部已经创建了一个
layer
与View
上下文关联
/控制器View将要显示的时候调用
//-(void)viewWillAppear:(BOOL)animated 方法之后调用
- (void)drawRect:(CGRect)rect {
//1.获取上下文
CGContextRef contextRef = UIGraphicsGetCurrentContext();
//2.创建线
UIBezierPath *path = [UIBezierPath bezierPath];
//设置起点
[path moveToPoint:CGPointMake(50, 200)];
//终点
[path addLineToPoint:CGPointMake(300, 30)];
//如果在添加线的时候 默认是从终点当做另一条线的起点
[path addLineToPoint:CGPointMake(300, 250)];
//设置颜色
[[UIColor blackColor] set];
//设置线宽
CGContextSetLineWidth(contextRef, 5.0f);
//设置链接点的 角度 枚举值
/*
kCGLineJoinMiter,
kCGLineJoinRound,
kCGLineJoinBevel
*/
CGContextSetLineJoin(contextRef, kCGLineJoinRound);
//CGContextSetBlendMode(contextRef, kCGBlendModeScreen);
//3.绘制
//UIBezierPath 是UIKit矿建,需要转化
CGContextAddPath(contextRef, path.CGPath);
//4.渲染到View上
CGContextStrokePath(contextRef);
}
2.贝塞尔曲线UIBezierPath
- 苹果封装的一个可快速创建绘制图形的类
- 其内部也是要实现:
- 1.获取上下文
- 2.描述路径
- 3.把路径添加到上下文
- 4.渲染上下文
- (void)drawRect:(CGRect)rect {
//创建路径
UIBezierPath *path = [UIBezierPath bezierPath];
//设置起点
[path moveToPoint:CGPointMake(50, 50)];
//设置终点
[path addLineToPoint:CGPointMake(300, 300)];
//绘制 描边
[path stroke];
//1.获取上下文
//2.描述路径
//3.把路径添加到上下文
//4.渲染上下文
}
2.1UIBezierPath
常用的类方法
2.1.1
bezierPathWithRect:
绘制简单的图形:矩形,长方形
- (void)drawRect:(CGRect)rect {
//创建路径
UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(50, 50, 200, 200)];
//描边
[path stroke];
}
03_rect.png
2.1.2
bezierPathWithRoundedRect: cornerRadius:
参数一:要绘制的图形点 参数二:是圆角半径,当圆角半径等于一半就是圆(宽度和高度相等的情况下)
- (void)drawRect:(CGRect)rect {
//创建路径
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(50, 50, 200, 100) cornerRadius:50];
path.lineWidth = 10.f;
[path stroke];
}
04_椭圆.png
2.1.3 绘制圆弧
+ (instancetype)bezierPathWithArcCenter:(CGPoint)center
radius:(CGFloat)radius
startAngle:(CGFloat)startAngle
endAngle:(CGFloat)endAngle
clockwise:(BOOL)clockwise
参数一: 圆心
参数二: 半径
参数三: 开始的角度
参数四: 结束的角度
参数五; 绘制的方向 (顺时针还是逆时针)
//创建路径
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:self.center radius:50 startAngle:M_PI endAngle:0 clockwise:YES];
path.lineWidth = 10.f;
[[UIColor redColor] set];
[path stroke];
// 起点是0
//顺时针正
//逆时针负
05_圆弧.png
2.1.4 UIBezierPath
二阶曲线
参数一:终点
参数二: 控制点
- (void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint
;
- (void)drawRect:(CGRect)rect {
//创建路径
UIBezierPath *path = [UIBezierPath bezierPath];
//设置起点
[path moveToPoint:CGPointMake(50, 200)];
//设置终点和控制点
[path addQuadCurveToPoint:CGPointMake(200, 50) controlPoint:CGPointMake(20, 20)];
//设置颜色
[[UIColor redColor] set];
//描边
[path stroke];
}
WX20190514-141555.png
2.1.5UIBezierPath
三阶曲线
- (void)drawRect:(CGRect)rect {
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(50, 200)];
[path addCurveToPoint:CGPointMake(270, 80) controlPoint1:CGPointMake(50, 80) controlPoint2:CGPointMake(200, 200)];
[[UIColor redColor] set];
[path stroke];
}
WX20190514-142254.png
下载进度的绘制 小demo
- 可用于 图片的展示(下载进度)
#import "CCDownloadProgressView.h"
@interface CCDownloadProgressView ()
@property (nonatomic, weak) UILabel *progressLabel;
@end
@implementation CCDownloadProgressView
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
}
return self;
}
- (void)awakeFromNib{
[super awakeFromNib];
}
//界面显示的时候调用
//核心代码
- (void)drawRect:(CGRect)rect {
//获取上下文
// CGContextRef ref = UIGraphicsGetCurrentContext();
//绘制路径
CGFloat width = rect.size.width *0.5;
CGFloat height = rect.size.height *0.5;
CGPoint center = CGPointMake(width, height);
CGFloat endAng = 2 *M_PI *self.progress + (-M_PI_2);
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:width - 10 startAngle:-M_PI_2 endAngle:endAng clockwise:YES];
//设置颜色
[self.circleColor set];
//把路径
[path stroke];
}
- (void)setProgress:(CGFloat)progress {
_progress = progress;
self.progressLabel.text = [NSString stringWithFormat:@"%.1f%%",progress *100];
//重新绘制
[self setNeedsDisplay];
}
- (void)setCircleColor:(UIColor *)circleColor{
_circleColor = circleColor;
self.progressLabel.textColor = circleColor;
}
- (void)layoutSubviews {
[super layoutSubviews];
self.progressLabel.frame = self.bounds;
}
- (UILabel *)progressLabel {
if (!_progressLabel) {
UILabel *contenLabel = [[UILabel alloc] init];
contenLabel.textAlignment = NSTextAlignmentCenter;
[self addSubview:contenLabel];
self.progressLabel = contenLabel;
}
return _progressLabel;
}
@end
3. 绘制文字
方法一
- (void)drawAtPoint:(CGPoint)point withAttributes:(nullable NSDictionary<NSAttributedStringKey, id> *)attrs
缺点:
这个方法 绘制出来的文字不能换行
//绘制文字
- (void)drawRect:(CGRect)rect {
NSString *text = @"这是一个文字的g绘制效果";
//设置 字体的属性
NSDictionary *att = @{
NSFontAttributeName:[UIFont systemFontOfSize:20],
NSForegroundColorAttributeName:[UIColor redColor]
};
[text drawAtPoint:CGPointZero withAttributes:att];
}
WX20190521-165012.png
方法二
//绘制文字
- (void)drawRect:(CGRect)rect {
NSString *text = @"这是一个文字的g绘制效果,这是一个文字的g绘制效果,这是一个文字的g绘制效果,这是一个文字的g绘制效果,这是一个文字的g绘制效果,这是一个文字的g绘制效果";
NSDictionary *att = @{
NSFontAttributeName:[UIFont systemFontOfSize:20],
NSForegroundColorAttributeName:[UIColor redColor]
};
[text drawInRect:CGRectMake(0, 0, 300, 300) withAttributes:att];
}
WX20190521-170925.png
方法三
- (void)drawWithRect:(CGRect)rect options:(NSStringDrawingOptions)options attributes:(nullable NSDictionary<NSAttributedStringKey, id> *)attributes context:(nullable NSStringDrawingContext *)context
这个方法,可以根据字体的多少,来计算高度
类似我们经常使用 计算文本高度的
方法
- (CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options attributes:(nullable NSDictionary<NSAttributedStringKey, id> *)attributes context:(nullable NSStringDrawingContext *)context
//绘制文字
- (void)drawRect:(CGRect)rect {
NSString *text = @"5月20日,习近平赴江西考察调研。上午,他到了位于赣州市区的江西金力永磁科技股份有限公司,下午的行程则集中在了赣州于都县。一周之前的中共中央政治局会议决定,从今年6月开始,在全党自上而下分两批开展“不忘初心、牢记使命”主题教育。在主题教育即将开展之际,习近平总书记此次到访中央红军长征集结出发地,引人关注";
NSDictionary *att = @{
NSFontAttributeName:[UIFont systemFontOfSize:20],
NSForegroundColorAttributeName:[UIColor redColor]
};
//设置宽度是300, 告诉是 无线大
CGSize textSize = CGSizeMake(300, MAXFLOAT);
[text drawWithRect:CGRectMake(0, 0, textSize.width, textSize.height) options:NSStringDrawingUsesLineFragmentOrigin attributes:att context:nil];
}
WX20190521-173523.png
补充:计算文本高度的方法
方式一
-
boundingRectWithSize:options:attributes:
方法,适用于换行的情况,也适用于不换行的情况,为了兼容两者的方法
//文本内容
CGSize chatContentSize = [self sizeWithText:text WithMaxSize:CGSizeMake(cellMaxw, MAXFLOAT) fontSize:contentTextFont];
//计算字体宽高
- (CGSize)sizeWithText:(NSString *)text WithMaxSize:(CGSize)maxSize fontSize:(CGFloat)fontSize
{
return [text boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:fontSize]} context:nil].size;
}
方式二
-
sizeWithAttributes:
计算文本宽度和高度,不会自动换行
NSString *text = @"5月20日,习近平赴江西考察调研。上午,他到了位于赣州市区的江西金力永磁科技股份有限公司,下午的行程则集中在了赣州于都县。一周之前的中共中央政治局会议决定,从今年6月开始,在全党自上而下分两批开展“不忘初心、牢记使命”主题教育。在主题教育即将开展之际,习近平总书记此次到访中央红军长征集结出发地,引人关注";
NSDictionary *att = @{
NSFontAttributeName:[UIFont systemFontOfSize:20],
NSForegroundColorAttributeName:[UIColor redColor]
};
CGSize textSize = [text sizeWithAttributes:att];
//打印高度
NSLog(@"%@",NSStringFromCGSize(textSize));
网友评论