也就是说苹果帮我们封装了一套绘图的函数库

iOS UI进阶05,iosui进阶

  • Quartz2D
    • Quartz2D是二维的绘图引擎
      • 经包装的函数库,方便开荒者使用。约等于说苹果帮大家封装了一套绘图的函数库
      • 用Quartz2D写的同一份代码,不仅能够运作在iphone上又能够运作在mac上,能够跨平台支付。
      • 开采中比较常用的是截屏/裁剪/自定义UI控件。
        Quartz2D在iOS开采中的价值正是自定义UI控件。
      • 在drawRect:方法中本事赢获得上下文

  • Quartz2D绘图

    • 自定义view:供给绘图,就亟须重写drawRect:方法

      • 1
        drawRect视图要来得的时候,才会调用,viewDidLoad后才会调用,因为那时候还没展现视图。
      • 2 成效:用来绘图
        • 画一条线
        • 1 获取图形上下文
        • CG:表示这几个类在CoreGraphics框架里 Ref:援用
        • 想获得图形上下文,首先敲UIGraphics。
        • 2
          拼接路线:一般开荒中用贝塞尔路线,里面封装了相当多事物,能够帮本身画一些中央的线条,矩形,圆等等。
        • 创设贝塞尔路线
        • 起点:moveToPoint
        • 终点:addLineToPoint
        • 3 把门路增加到上下文
      • CGPath转换:UIKit框架转CoreGraphics直接CGPath就能转

        • 4> 把上下文渲染到视图,图形上下文本人不持有展现效果。
        • 5计算:首先获得图形上下文,然后陈诉路径,把门路加多到上下文,渲染到视图,图形上下文相当于贰个内部存款和储蓄器缓存区,在内部存款和储蓄器里面操作是最快的,比一直在分界面操作快多了。
        • // 几时调用:当前控件将要展现的时候才会调用那么些办法绘制

             // 作用:绘制内容,以后只要想在一个view中绘制内容,必须在drawRect里面绘制
             - (void)drawRect:(CGRect)rect {
          
              // 绘制曲线
              // 1.获取上下文
              CGContextRef ctx = UIGraphicsGetCurrentContext();
          
              // 2.拼接路径
              UIBezierPath *path = [UIBezierPath bezierPath];
          
              // 设置起点
              [path moveToPoint:CGPointMake(10, 125)];
          
              // 描述曲线
              [path addQuadCurveToPoint:CGPointMake(240, 125) controlPoint:CGPointMake(125, 240)];
          
              [path addLineToPoint:CGPointMake(10, 125)];
          
              // 3.添加路径到上下文
              CGContextAddPath(ctx, path.CGPath);
          
              // 设置绘图状态,一定要再渲染之前
              // 设置颜色
              [[UIColor redColor] setStroke];
          
              // 设置线段的宽度
              CGContextSetLineWidth(ctx, 15);
              // 设置线段的顶角样式
              CGContextSetLineCap(ctx, kCGLineCapRound);
          
              // 设置连接样式
              CGContextSetLineJoin(ctx, kCGLineJoinRound);
          
              // 4.渲染上下文
              CGContextStrokePath(ctx);
          }
          
      • 画两跟不总是的线

        • 1
          第一遍画的时候,重新安装起源,然后画线。三个路子能够涵盖多条线条。
        • 2
          新创设一个门路,增多到上下文。开垦中国建工业总会公司议利用这种,比较易于调整每根线。
        • // 绘制两条门路的方法

          - (void)drawTwoLine
          {
              // 1.获取上下文
              CGContextRef ctx = UIGraphicsGetCurrentContext();
          
              // 2.拼接路径,一个路径中可以保存多条线段
              UIBezierPath *path = [UIBezierPath bezierPath];
          
              [path moveToPoint:CGPointMake(10, 10)];
          
              [path addLineToPoint:CGPointMake(20, 20)];
          
                    // 3.把路径添加到上下文
                    CGContextAddPath(ctx, path.CGPath);

                    // 一根线对应一个路径,只要绘制的线不连接,最好使用一根线对应一个路径的方法
                    path = [UIBezierPath bezierPath];
                    // 拼接另一根直线
                    // 默认下一根线的起点就是上一根线的终点
                    // 设置第二根线的起点
                    //    [path moveToPoint:CGPointMake(20, 20)];
                    // 如果想要绘制不连接的线,重新设置起点
                    [path moveToPoint:CGPointMake(50, 50)];

                    [path addLineToPoint:CGPointMake(20, 200)];

                    // 3.把路径添加到上下文
                    CGContextAddPath(ctx, path.CGPath);

                    // 4.渲染上下文
                    CGContextStrokePath(ctx);

                }

    -   圆弧
        -   分析:
            -   1> 圆弧属于圆的一部分,因此先要有圆,才有弧。
            -   2> 圆需要起点吗?画线需要,圆也不另外。 -3>
                起点在哪? 圆心右边
            -   4>
                画圆弧还需要起始角度,结束角度,方向,角度必须是弧度
            -   // 画圆弧
                        // Center圆心
                        // radius:半径
                        // startAngle起始角度
                        // endAngle:结束角度
                        // clockwise:Yes 顺时针 No逆时针
                        CGPoint center = CGPointMake(self.bounds.size.width * 0.5, self.bounds.size.height * 0.5);
                        UIBezierPath *path1 = [UIBezierPath bezierPathWithArcCenter:center radius:100 startAngle:0 endAngle:M_PI_2 clockwise:NO];

                        [path1 stroke];
    -   画扇形
        -   // 画扇形
                    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:100 startAngle:0 endAngle:M_PI_2 clockwise:YES];

                    [path addLineToPoint:center];

                    [path addLineToPoint:CGPointMake(self.bounds.size.height * 0.5 + 100, self.bounds.size.height * 0.5)];
                    // 关闭路径:从路径的终点连接到起点
                    [path closePath];
                    // 设置填充颜色
                    [[UIColor redColor] setFill];

                    // 设置描边颜色
                    [[UIColor greenColor] setStroke];

                    //    [path stroke];
                    // 如果路径不是封闭的,默认会关闭路径
                    [path fill];

    -   画饼图
        -   #import "PieView.h"

                @implementation PieView


                // Only override drawRect: if you perform custom drawing.
                // An empty implementation adversely affects performance during animation.

                - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
                {
                   //重绘
                    [self setNeedsDisplay];
                }

                - (void)drawRect:(CGRect)rect {
                    // Drawing code

                    NSArray *data = @[@25,@25,@20,@30];

                    //圆心
                    CGPoint center = CGPointMake(self.bounds.size.width * 0.5, self.bounds.size.height * 0.5);
                    //角度
                    CGFloat radius = self.bounds.size.width * 0.5;
                    CGFloat startA = 0;
                    CGFloat endA = 0;
                    CGFloat angle = 0;

                    for (NSNumber *num in data) {
                        // 画一个扇形
                        startA = endA;
                        angle = [num intValue] / 100.0 * M_PI * 2;
                        endA = startA + angle;

                       UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startA endAngle:endA clockwise:YES];

                        [path addLineToPoint:center];

                        // set:同时设置描边和填充颜色
                        [[self randomColor] set];

                        [path fill];

                    }

                }

                // 随机颜色
                - (UIColor *)randomColor
                {
                    CGFloat r = arc4random_uniform(256) / 255.0;
                    CGFloat g = arc4random_uniform(256) / 255.0;
                    CGFloat b = arc4random_uniform(256) / 255.0;
                    return [UIColor colorWithRed:r green:g blue:b alpha:1];
                }



                @end
                效果图:

    -   画字
        -   - (void)drawRect:(CGRect)rect {

                    NSString *str = @"hello!";

                    // Attributes:属性
                    // 给一个字符串添加属性,可以叫富文本,颜色,字体大小,空心,阴影

                    // 利用这个属性字典给文本添加属性
                    NSMutableDictionary *strAttr = [NSMutableDictionary dictionary];
                    // key,value
                    // 如何找到设置文本的属性key
                    // 描述了字体
                    strAttr[NSFontAttributeName] = [UIFont boldSystemFontOfSize:50];

                    // 设置描边的颜色和宽度
                    strAttr[NSStrokeWidthAttributeName] = @1;

                    strAttr[NSStrokeColorAttributeName] = [UIColor redColor];

                    NSShadow *shadow = [[NSShadow alloc] init];

                    shadow.shadowColor = [UIColor yellowColor];

                    shadow.shadowOffset = CGSizeMake(10, 10);

                    shadow.shadowBlurRadius = 5;

                    // 阴影
                    strAttr[NSShadowAttributeName] = shadow;

                    // 文字颜色
                    strAttr[NSForegroundColorAttributeName] = [UIColor redColor];

                    [str drawAtPoint:CGPointZero withAttributes:strAttr];

                }
                 效果图:

             
-   定时器实现下雪
    -   -   #import "SnowView.h"

                @implementation SnowView


                - (void)awakeFromNib
                {
                    // 设置定时器
                //    [NSTimer scheduledTimerWithTimeInterval:.1 target:self selector:@selector(setNeedsDisplay) userInfo:nil repeats:YES];

                    // 0.1 setNeedsDisplay 绑定一个标识,等待下次刷新的时候才会调用drawRect方法
                    // 0.15 屏幕的刷新时间

                    // 定时器
                    // 每次屏幕刷新的时候就会调用,屏幕一秒刷新60次
                    CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(setNeedsDisplay)];

                    // 只要把定时器添加到主运行循环就能自动执行
                    [link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];

                    // setNeedsDisplay:底层并不会马上调用drawRect,只会给当前的控件绑定一个刷新的标识,每次屏幕刷新的时候,就会把绑定了刷新(重绘)标识的控件重新刷新(绘制)一次,就会调用drawRect去重绘

                    // 如果以后每隔一段时间需要重绘,一般不使用NSTimer,使用CADisplayLink,不会刷新的时候有延迟
                }

                // Only override drawRect: if you perform custom drawing.
                // An empty implementation adversely affects performance during animation.
                - (void)drawRect:(CGRect)rect {
                    // Drawing code

                    static CGFloat snowY = 0;

                    UIImage *image = [UIImage imageNamed:@"雪花"];

                    [image drawAtPoint:CGPointMake(0, snowY)];

                    snowY += 10;

                    if (snowY > rect.size.height) {
                        snowY = 0;
                    }


                }
                效果图:

             

-   图形上下文状态栈
    -   -   #import "DrawView.h"

                @implementation DrawView


                // Only override drawRect: if you perform custom drawing.
                // An empty implementation adversely affects performance during animation.
                - (void)drawRect:(CGRect)rect {
                    // Drawing code
                    // 1.获取上下文
                    CGContextRef ctx = UIGraphicsGetCurrentContext();

                    // 2.拼接路径
                    UIBezierPath *path = [UIBezierPath bezierPath];

                    [path moveToPoint:CGPointMake(10, 125)];

                    [path addLineToPoint:CGPointMake(240, 125)];

                    // 3.把路径添加到上下文
                    CGContextAddPath(ctx, path.CGPath);

                    // 保存当前上下文的默认状态
                    CGContextSaveGState(ctx);

                    // 设置状态
                    [[UIColor redColor] set];

                    CGContextSetLineWidth(ctx, 20);

                    // 渲染上下文
                    CGContextStrokePath(ctx);

                    // 创建第二根路径
                    path = [UIBezierPath bezierPath];
                    [path moveToPoint:CGPointMake(125, 10)];
                    [path addLineToPoint:CGPointMake(125, 240)];

                    // 添加到上下文
                    CGContextAddPath(ctx, path.CGPath);

                    // 恢复下上下文状态
                    // 取出之前的保存的状态覆盖掉当前的状态
                    CGContextRestoreGState(ctx);
                //    [[UIColor blackColor] set];
                //    CGContextSetLineWidth(ctx, 1);

                    // 4.渲染上下文到view的layer
                    // 在渲染之前,系统会查看下上下文的状态,根据状态去渲染
                    CGContextStrokePath(ctx);

                }

                @end

    -   图片截屏
        -   #import "ViewController.h"

                @interface ViewController ()

                @property (nonatomic, weak) UIView *cover;

                @property (nonatomic, assign) CGPoint oriP;

                @property (weak, nonatomic) IBOutlet UIImageView *imageView;
                @property (weak, nonatomic) IBOutlet UIView *view1;

                @end

                @implementation ViewController

                - (UIView *)cover
                {
                    if (_cover == nil) {
                        UIView *view = [[UIView alloc] init];


                        view.backgroundColor = [UIColor blackColor];
                        view.alpha = 0.5;

                        _cover = view;

                        [self.view addSubview:view];

                    }
                    return _cover;
                }

                - (IBAction)pan:(UIPanGestureRecognizer *)sender {
                    // 获取下当前的触摸
                    CGPoint curP = [sender locationInView:_imageView];
                    if (sender.state == UIGestureRecognizerStateBegan) {
                        // 记录下一开始的位置
                        _oriP = curP;
                    }

                    // 计算下黑色蒙版的frame
                    CGFloat w = curP.x - _oriP.x;
                    CGFloat h = curP.y - _oriP.y;

                    self.cover.frame = CGRectMake(_oriP.x, _oriP.y, w, h);


                    if (sender.state == UIGestureRecognizerStateEnded) { // 手指抬起

                        // 裁剪图片,生成一张新图片

                        // 开启位图上下文
                        UIGraphicsBeginImageContextWithOptions(_imageView.bounds.size, NO, 0);

                        // 设置裁剪区域
                        UIBezierPath *path = [UIBezierPath bezierPathWithRect:self.cover.frame];
                        [path addClip];


                        // 绘制图片
                        [_imageView.layer renderInContext:UIGraphicsGetCurrentContext()];

                        // 生成图片
                        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

                        // 关闭上下文
                        UIGraphicsEndImageContext();

                        _imageView.image = image;

                        [self.cover removeFromSuperview];


                    }


                }
                @end
                效果图:截屏前

                效果图:截屏后

                 

    -   图片擦除
        -   #import "ViewController.h"

                @interface ViewController ()

                @end

                @implementation ViewController
                // 只要用户手指在图片上拖动.就会调用
                - (IBAction)pan:(UIPanGestureRecognizer *)sender {
                    // 拖动的时候,擦除图片的某一部分

                    // 获取手指的触摸点
                   CGPoint curP = [sender locationInView:sender.view];

                    // 计算擦除的frame
                    CGFloat wh = 30;
                    CGFloat x = curP.x - wh * 0.5;
                    CGFloat y = curP.y - wh * 0.5;

                    CGRect frame = CGRectMake(x, y, wh, wh);

                    // 开启位图上下文
                    UIGraphicsBeginImageContextWithOptions(sender.view.bounds.size, NO, 0);

                    // 获取当前的上下文
                    CGContextRef ctx = UIGraphicsGetCurrentContext();

                    // 把控件上的内容渲染到上下文
                    [sender.view.layer renderInContext:ctx];

                    // 清除上下文中某一部分的内容
                    CGContextClearRect(ctx, frame);

                    // 生成一张新的图片
                    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

                    // 关闭上下文
                    UIGraphicsEndImageContext();

                    // 重新显示到UIImageView
                    UIImageView *imageV = (UIImageView *)sender.view;

                    imageV.image = image;

                }

                @end
                效果图:擦除前:
                效果图:擦除部分后:

             

UI进级05,iosui升级 Quartz2D
Quartz2D是二维的绘图引擎
经包装的函数库,方便开采者使用。也正是说苹果帮大家封装了一套绘图的函数库
用…

相关文章