iOS之QuartZ 2D 绘图(一)

Quartz2D

  • Quartz2D是苹果封装的一个库,针对iOS和os系统绘制不同的类型的制图方式
  • 图形上下文(一种数据类型,类似int,double)数据类型(CGContextRef)
  • 不同的上下文(数据类型)可以绘制不同的类型(pdf,bitmap,layer,window,ptinter)
  • 进而上面5中类型,对应不同的上下文

1. 绘制简单图形 -> 画线

  • 在自定义的View我们可以通知drawRect:方法绘制,自己想要的线条
  • 苹果内部已经创建了一个layerView上下文关联在这里插入图片描述
/控制器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];
    
    
}

在这里插入图片描述

2.1.2bezierPathWithRoundedRect: cornerRadius:

参数一:要绘制的图形点 参数二:是圆角半径,当圆角半径等于一半就是圆(宽度和高度相等的情况下)

- (void)drawRect:(CGRect)rect {
    
    //创建路径
    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
参数一: 圆心
参数二: 半径
参数三: 开始的角度
参数四: 结束的角度
参数五; 绘制的方向 (顺时针还是逆时针)

   //创建路径
    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二阶曲线

参数一:终点
参数二: 控制点
- (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];
    
}

Alt

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

//界面显示的时候调用
//核心代码
- (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];
   
  
}


在这里插入图片描述

方法二
//绘制文字
- (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
这个方法,可以根据字体的多少,来计算高度
类似我们经常使用 计算 文本高度的方法

- (CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options attributes:(nullable NSDictionary<NSAttributedStringKey, id> *)attributes context:(nullable NSStringDrawingContext *)context


//绘制文字
- (void)drawRect:(CGRect)rect {
    
    NSString *text = @"这是计算文字高度的方法,到了位于赣州市区的江西金力永磁科技股份有限公司,下午的行程则集中在了赣州于都县。哈哈哈,测试一下看看看行不行";
    
    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];
   
    
}



补充:计算文本高度的方法
方式一
  • 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 = @"计算稿。计算高度,哈哈哈,啦啦啦啦啦,他是放下了,才说出来,我是不是也该放下了,直到今日才明白我一个人自以为刻骨铭心的回忆,他也许早就忘怀,他的短篇小说故事中我没有丝言片语,也许若干年后他回想起来的只是我的名字,我只是个戏子,在他的故事中流着自己的泪,一个于他青春年华中不曾使他掀起过一丝波澜的模糊影子";
    
    NSDictionary *att = @{
                          NSFontAttributeName:[UIFont systemFontOfSize:20],
                          NSForegroundColorAttributeName:[UIColor redColor]
                          
                          };
    
  
    CGSize textSize = [text sizeWithAttributes:att];
    //打印高度
   NSLog(@"%@",NSStringFromCGSize(textSize));

图形上下文的状态栈

在这里插入图片描述

在这里插入图片描述

  • //保存系统的上下文到 上下文栈中 CGContextSaveGState(ref);

  • //从上下文栈中 获取保存的状态 CGContextRestoreGState(ref);


- (void)drawRect:(CGRect)rect {

    
    //获取图形上下文
    CGContextRef ref = UIGraphicsGetCurrentContext();
    
    UIBezierPath *path = [UIBezierPath bezierPath];
    
    [path moveToPoint:CGPointMake(50, 100)];
    [path addLineToPoint:CGPointMake(240, 100)];
    
    //保存系统的上下文到 上下文栈中
    CGContextSaveGState(ref);
    //设置状态
    [[UIColor redColor] set];
    path.lineWidth = 5;
    //添加路径
    CGContextAddPath(ref, path.CGPath);
    //绘制渲染
    CGContextStrokePath(ref);
    
    //创建路径2
    UIBezierPath *path2 = [UIBezierPath bezierPath];
    
    [path2 moveToPoint:CGPointMake(190, 50)];
    [path2 addLineToPoint:CGPointMake(190, 200)];
    
    //从上下文栈中 获取保存的状态
    CGContextRestoreGState(ref);

    //添加路径
    CGContextAddPath(ref, path2.CGPath);
    //绘制渲染
    CGContextStrokePath(ref);
    
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值