美文网首页iOS开发
iOS之QuartZ 2D 绘图(一)

iOS之QuartZ 2D 绘图(一)

作者: 追逐_chase | 来源:发表于2019-05-21 16:19 被阅读0次

    Quartz2D

    • Quartz2D是苹果封装的一个库,针对iOS和os系统绘制不同的类型的制图方式

    • 图形上下文(一种数据类型,类似int,double)数据类型(CGContextRef)

    • 不同的上下文(数据类型)可以绘制不同的类型(pdf,bitmap,layer,window,ptinter)

    • 进而上面5中类型,对应不同的上下文

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

    • 在自定义的View我们可以通知drawRect:方法绘制,自己想要的线条
    • 苹果内部已经创建了一个layerView上下文关联
    01_line.png
    /控制器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.2bezierPathWithRoundedRect: 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

    • 可用于 图片的展示(下载进度)
    110.gif
    
    #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));
    
    

    相关文章

      网友评论

        本文标题:iOS之QuartZ 2D 绘图(一)

        本文链接:https://www.haomeiwen.com/subject/jpesaqtx.html