Quartz2D
Quartz2D是蘋果封裝的一個庫,針對iOS和os系統(tǒng)繪制不同的類型的制圖方式
圖形上下文(一種數(shù)據(jù)類型,類似int,double)數(shù)據(jù)類型(
CGContextRef)不同的
上下文(數(shù)據(jù)類型)可以繪制不同的類型(pdf,bitmap,layer,window,ptinter)進而上面5中類型,對應(yīng)不同的
上下文
1. 繪制簡單圖形 -> 畫線
- 在自定義的
View我們可以通知drawRect:方法繪制,自己想要的線條 - 蘋果內(nèi)部已經(jīng)創(chuàng)建了一個
layer與View上下文關(guān)聯(lián)

/控制器View將要顯示的時候調(diào)用
//-(void)viewWillAppear:(BOOL)animated 方法之后調(diào)用
- (void)drawRect:(CGRect)rect {
//1.獲取上下文
CGContextRef contextRef = UIGraphicsGetCurrentContext();
//2.創(chuàng)建線
UIBezierPath *path = [UIBezierPath bezierPath];
//設(shè)置起點
[path moveToPoint:CGPointMake(50, 200)];
//終點
[path addLineToPoint:CGPointMake(300, 30)];
//如果在添加線的時候 默認是從終點當做另一條線的起點
[path addLineToPoint:CGPointMake(300, 250)];
//設(shè)置顏色
[[UIColor blackColor] set];
//設(shè)置線寬
CGContextSetLineWidth(contextRef, 5.0f);
//設(shè)置鏈接點的 角度 枚舉值
/*
kCGLineJoinMiter,
kCGLineJoinRound,
kCGLineJoinBevel
*/
CGContextSetLineJoin(contextRef, kCGLineJoinRound);
//CGContextSetBlendMode(contextRef, kCGBlendModeScreen);
//3.繪制
//UIBezierPath 是UIKit礦建,需要轉(zhuǎn)化
CGContextAddPath(contextRef, path.CGPath);
//4.渲染到View上
CGContextStrokePath(contextRef);
}
2.貝塞爾曲線UIBezierPath
- 蘋果封裝的一個可快速創(chuàng)建繪制圖形的類
- 其內(nèi)部也是要實現(xiàn):
- 1.獲取上下文
- 2.描述路徑
- 3.把路徑添加到上下文
- 4.渲染上下文
- (void)drawRect:(CGRect)rect {
//創(chuàng)建路徑
UIBezierPath *path = [UIBezierPath bezierPath];
//設(shè)置起點
[path moveToPoint:CGPointMake(50, 50)];
//設(shè)置終點
[path addLineToPoint:CGPointMake(300, 300)];
//繪制 描邊
[path stroke];
//1.獲取上下文
//2.描述路徑
//3.把路徑添加到上下文
//4.渲染上下文
}
2.1UIBezierPath常用的類方法
2.1.1
bezierPathWithRect:繪制簡單的圖形:矩形,長方形
- (void)drawRect:(CGRect)rect {
//創(chuàng)建路徑
UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(50, 50, 200, 200)];
//描邊
[path stroke];
}

2.1.2
bezierPathWithRoundedRect: cornerRadius:參數(shù)一:要繪制的圖形點 參數(shù)二:是圓角半徑,當圓角半徑等于一半就是圓(寬度和高度相等的情況下)
- (void)drawRect:(CGRect)rect {
//創(chuàng)建路徑
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(50, 50, 200, 100) cornerRadius:50];
path.lineWidth = 10.f;
[path stroke];
}

2.1.3 繪制圓弧
+ (instancetype)bezierPathWithArcCenter:(CGPoint)center
radius:(CGFloat)radius
startAngle:(CGFloat)startAngle
endAngle:(CGFloat)endAngle
clockwise:(BOOL)clockwise
參數(shù)一: 圓心
參數(shù)二: 半徑
參數(shù)三: 開始的角度
參數(shù)四: 結(jié)束的角度
參數(shù)五; 繪制的方向 (順時針還是逆時針)
//創(chuàng)建路徑
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
//順時針正
//逆時針負

2.1.4 UIBezierPath二階曲線
參數(shù)一:終點
參數(shù)二: 控制點
- (void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint;
- (void)drawRect:(CGRect)rect {
//創(chuàng)建路徑
UIBezierPath *path = [UIBezierPath bezierPath];
//設(shè)置起點
[path moveToPoint:CGPointMake(50, 200)];
//設(shè)置終點和控制點
[path addQuadCurveToPoint:CGPointMake(200, 50) controlPoint:CGPointMake(20, 20)];
//設(shè)置顏色
[[UIColor redColor] set];
//描邊
[path stroke];
}

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];
}

下載進度的繪制 小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];
}
//界面顯示的時候調(diào)用
//核心代碼
- (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];
//設(shè)置顏色
[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繪制效果";
//設(shè)置 字體的屬性
NSDictionary *att = @{
NSFontAttributeName:[UIFont systemFontOfSize:20],
NSForegroundColorAttributeName:[UIColor redColor]
};
[text drawAtPoint:CGPointZero withAttributes:att];
}

方法二
//繪制文字
- (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];
}

方法三
- (void)drawWithRect:(CGRect)rect options:(NSStringDrawingOptions)options attributes:(nullable NSDictionary<NSAttributedStringKey, id> *)attributes context:(nullable NSStringDrawingContext *)context
這個方法,可以根據(jù)字體的多少,來計算高度
類似我們經(jīng)常使用 計算文本高度的方法
- (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日,習近平赴江西考察調(diào)研。上午,他到了位于贛州市區(qū)的江西金力永磁科技股份有限公司,下午的行程則集中在了贛州于都縣。一周之前的中共中央政治局會議決定,從今年6月開始,在全黨自上而下分兩批開展“不忘初心、牢記使命”主題教育。在主題教育即將開展之際,習近平總書記此次到訪中央紅軍長征集結(jié)出發(fā)地,引人關(guān)注";
NSDictionary *att = @{
NSFontAttributeName:[UIFont systemFontOfSize:20],
NSForegroundColorAttributeName:[UIColor redColor]
};
//設(shè)置寬度是300, 告訴是 無線大
CGSize textSize = CGSizeMake(300, MAXFLOAT);
[text drawWithRect:CGRectMake(0, 0, textSize.width, textSize.height) options:NSStringDrawingUsesLineFragmentOrigin attributes:att context:nil];
}

補充:計算文本高度的方法
方式一
-
boundingRectWithSize:options:attributes:方法,適用于換行的情況,也適用于不換行的情況,為了兼容兩者的方法
//文本內(nèi)容
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日,習近平赴江西考察調(diào)研。上午,他到了位于贛州市區(qū)的江西金力永磁科技股份有限公司,下午的行程則集中在了贛州于都縣。一周之前的中共中央政治局會議決定,從今年6月開始,在全黨自上而下分兩批開展“不忘初心、牢記使命”主題教育。在主題教育即將開展之際,習近平總書記此次到訪中央紅軍長征集結(jié)出發(fā)地,引人關(guān)注";
NSDictionary *att = @{
NSFontAttributeName:[UIFont systemFontOfSize:20],
NSForegroundColorAttributeName:[UIColor redColor]
};
CGSize textSize = [text sizeWithAttributes:att];
//打印高度
NSLog(@"%@",NSStringFromCGSize(textSize));