zoukankan      html  css  js  c++  java
  • iOS——Quartz2D


    0. 复习。




    1.基本图形绘制

    * 线段(线宽、线段样式)

    * 矩形(空心、实心、颜色)

    * 三角形、四边形等形状


    1> 说明 - (void)drawRect:(CGRect)rect 什么时候调用、调用次数等

    - view 第一次被显示的时候调用(调用一次)

    - 或者是重绘事件被触发的时候

    - 不要手动去调用这种方法

    - 手动调用重绘方法 setNeedsDisplay 或者 setNeedsDisplayInRect:


    2> 说明为什么要在 - (void)drawRect:(CGRect)rect 方法中进行画图

    - 仅仅有在这种方法中才干获取当前 View 的画图上下文


    /**

     1. 当要向UIView上画图的时候, 必须重写UIViewdrawRect:方法, 然后在这种方法中进行画图

     2. drawRect:方法中获取的參数rect, 指的就是当前viewbounds属性

     3. 为什么向当前view中绘制图形, 必须在drawRect:方法中进行?

     3.1 原因: 仅仅有在当前viewdrawRect:方法中才干成功的获取当前view"图形上下文", 有了图形上下文才干进行画图

     3.2 为什么仅仅有在drawRect:方法中才干获取当前view的图形上下文呢?

     3.3 原因: 是由于系统在调用drawRect:方法之前已经帮我们创建好了一个与当前view相关的图形上下文了, 然后才调用的drawRect:方法, 所以在drawRect:方法中, 我们就能够成功获取当前view的图形上下文了。

     3.4 怎样创建一个图形上下文?(后面说)

     3.5 drawRect:方法是谁来调用的?什么时候调用的?

     3.5.1 drawRect:方法是系统帮我们调用的, 千万别手动去调用这种方法。原因是, 自己手动去调用drawRect:方法的时候无法保证系统已经帮我们创建好了"图形上下文", 所以这样就无法保证在drawRect:方法中获取"图形上下文"对象, 所以也就无法画图。

     3.5.2 drawRect:方法的什么时候被调用?

              1> 当这个View第一次显示的时候会条用一次drawRect:方法。

              2> 当这个View运行重绘操作的时候, 会又一次调用drawRect:方法来进行画图。

              3> 通过调用【[self setNeedsDisplay];// 把这个view都重绘一次】 [self setNeedsDisplayInRect:(CGRect)]// view中的某个区域重绘一次】 来实现重绘

              4> 在每次调用 setNeedsDisplay setNeedsDisplayInRect:方法的时候, 内部会先创建一个与当前view相关连的"图形上下文"然后再调用drawRect:实现重绘。

    */


    案例:

    1> 绘制一根线段

    /** 參考代码:

     

     void test1()

     {

         // 1. 获取当前的图形上下文

         CGContextRef ctx = UIGraphicsGetCurrentContext();

         

         // 2. 在上下文中绘制图形(拼接路径)

         // 2.1 设置一个起点

         CGContextMoveToPoint(ctx, 20, 20);

         // 2.2 加入一条直线到(100, 100)这个点

         CGContextAddLineToPoint(ctx, 100, 20);

         

         

         // 3. 把上下文渲染显示到 HMView01

        // StrokePath 表示把路径以空心的形式渲染出来。

         CGContextStrokePath(ctx);

     }

     

     */


    2> 绘制一个中文"", 两根线段

    /** 參考代码:

     

     void test2()

     {

         // 1. 获取当前的图形上下文

         CGContextRef ctx = UIGraphicsGetCurrentContext();

         

         // 2. 在上下文中绘制图形(拼接路径)

         // 2.1 设置一个起点

         CGContextMoveToPoint(ctx, 20, 20);

         // 2.2 加入一条直线到(100, 100)这个点

         CGContextAddLineToPoint(ctx, 100, 20);

         

         

         // 2.3 再又一次设置一个起点

         CGContextMoveToPoint(ctx, 5, 50);

         // 2.4 再加入一条线

         CGContextAddLineToPoint(ctx, 115, 50);

         

         

         // 3. 把上下文渲染显示到 HMView01

        // StrokePath 表示把路径以空心的形式渲染出来。

         CGContextStrokePath(ctx);

     }

     

     */


    3> 绘制一个"三角形"

    /** 參考代码:

     

     void test3()

     {

         // 1. 获取当前的图形上下文

         CGContextRef ctx = UIGraphicsGetCurrentContext();

         

         // 2. 在上下文中绘制图形(拼接路径)

         // 2.1 设置一个起点

         CGContextMoveToPoint(ctx, 20, 20);

         // 2.2 加入一条直线到(100, 100)这个点

         CGContextAddLineToPoint(ctx, 100, 100);

         

         // 2.3 再加入一条线

         CGContextAddLineToPoint(ctx, 120, 30);

         

         // 2.4 再加入一条线段

         //CGContextAddLineToPoint(ctx, 20, 20);

         // 第二种做法: 直接关闭路径(连接最后一个点和起点)

         CGContextClosePath(ctx);

         

         

         // 3. 把上下文渲染显示到 HMView01

         // StrokePath 表示把路径以空心的形式渲染出来。

         CGContextStrokePath(ctx);

     }

     

     */


    4> 绘制一个"矩形"

    * 思路1: 能够画4根线来表示一个矩形。

    /** 參考代码:

     // 绘制四边形, 这样的画法, 仅仅能话""的图形, ""的须要使用"矩阵"的方式来进行旋转

     void test4()

     {

         // 绘制一个"四边形"

         // 1. 获取当前图形上下文

         CGContextRef ctx = UIGraphicsGetCurrentContext();

         

         // 2. 開始绘制路径

         CGContextAddRect(ctx, CGRectMake(20, 20, 100, 120));

         

         // 3. 渲染

         CGContextStrokePath(ctx);

     }

     */


    5> 绘制一个实心"矩形"

    /** 參考代码:

        // 绘制"实心"矩形, 仅仅要把 Stroke 变成 Fill 就可以

        void test5()

        {

            // 绘制一个"四边形"

            // 1. 获取当前图形上下文

            CGContextRef ctx = UIGraphicsGetCurrentContext();

            

            // 2. 開始绘制路径

            CGContextAddRect(ctx, CGRectMake(20, 20, 100, 120));

            

            // 3. 渲染

            CGContextFillPath(ctx);

            

        }

     */



    6.1> 设置图形的颜色

    /** 參考代码:

     

    // 设置图形的颜色

    void test6()

    {

         // 绘制一个"四边形"

         // 1. 获取当前图形上下文

         CGContextRef ctx = UIGraphicsGetCurrentContext();

         

         // 2. 開始绘制路径

         CGContextAddRect(ctx, CGRectMake(20, 20, 100, 120));

         

         

         

         //============ C 语言的方式设置颜色 =================

         

         CGContextSetRGBFillColor(ctx, 200/255.0, 100/255.0, 50/255.0, 1.0);

         //CGContextSetRGBStrokeColor(<#CGContextRef context#>, <#CGFloat red#>, <#CGFloat green#>, <#CGFloat blue#>, <#CGFloat alpha#>)

         

         //============ C 语言的方式设置颜色 =================

         

         

         

         //============ OC 的方式设置颜色 =================

         // 设置空心图形的线条颜色

         // [[UIColor redColor] setStroke];

         

         // 设置实心图形的填充颜色

         // [[UIColor redColor] setFill];

         

         // 统一设置"空心图形" "实心图形"的颜色

         //[[UIColor redColor] set];

         //============ OC 的方式设置颜色 =================

         

         

         

         // 3. 渲染

         CGContextFillPath(ctx);

    }

    */



    6.2> 设置不同线段, 不同颜色

    /** 參考代码

     

    void test8()

    {

        //画两根线, 一根红色, 一根蓝色

        // 1. 获取上下文对象

        CGContextRef ctx = UIGraphicsGetCurrentContext();

        

        

        // 2. 绘制图形

        // 2.1 设置起点

        CGContextMoveToPoint(ctx, 50, 50);

        // 2.2 加入一根线

        CGContextAddLineToPoint(ctx, 50, 150);

        

        // 2.3 设置线段颜色

        [[UIColor redColor] set];

        // 2.4 设置线宽

        CGContextSetLineWidth(ctx, 10);

        // 渲染一次

        CGContextStrokePath(ctx);

        

        

        

        

        // 再移动到一个新的起点

        CGContextMoveToPoint(ctx, 100, 50);

        // 再加入一根线

        CGContextAddLineToPoint(ctx, 100, 150);

        // 设置线的颜色

        [[UIColor blueColor] set];

        

        

        // 3. 渲染"上下文对象" view

        CGContextStrokePath(ctx);

    }

     

     */




    7> 设置线段宽度(也能够使用这样的方式绘制"实心矩形"

    /** 參考代码:

     

    // 设置线段宽度

    void test7()

    {

        // 绘制一个"四边形"

        // 1. 获取当前图形上下文

        CGContextRef ctx = UIGraphicsGetCurrentContext();

        

        // 2. 開始绘制路径

        CGContextAddRect(ctx, CGRectMake(20, 20, 100, 120));

        

        // 设置空心图形的线条颜色

        // [[UIColor redColor] setStroke];

        

        // 设置实心图形的填充颜色

        // [[UIColor redColor] setFill];

        

        // 统一设置"空心图形" "实心图形"的颜色

        [[UIColor redColor] set];

        

        // 设置线段宽度

        CGContextSetLineWidth(ctx, 20);

        

        // 3. 渲染

        CGContextStrokePath(ctx);

    }

    */



    * 解释:

    1> 拼接路径

    /** 參考代码:

     

     // 2. 在上下文中绘制图形(拼接路径)

     // 2.1 设置一个起点

     CGContextMoveToPoint(ctx, 20, 20);

     // 2.2 加入一条直线到(100, 100)这个点

     CGContextAddLineToPoint(ctx, 100, 100);

     

     // 2.3 再加入一条线

     CGContextAddLineToPoint(ctx, 120, 30);

     

     */

    2> 设置状态

    /** 參考代码:

     

     // 统一设置"空心图形" "实心图形"的颜色

     [[UIColor redColor] set];

     

     // 设置线段宽度

     CGContextSetLineWidth(ctx, 20);

     

     

     */






    8> 设置线段"头尾部"的样式

    /** 參考代码:

     

     void test9()

     {

         // 1. 获取上下文对象

         CGContextRef ctx = UIGraphicsGetCurrentContext();

         

         // 2. 绘制路径

         // 2.1 移动到起点

         CGContextMoveToPoint(ctx, 20, 20);

         

         // 2.2 加入一条线段

         CGContextAddLineToPoint(ctx, 100, 100);

         

         // 2.3 设置颜色

         [[UIColor redColor] set];

         

         

         // 2.4 设置线段宽度

         CGContextSetLineWidth(ctx, 15);

         

         // 2.5 设置线段头尾部样式


     //enum CGLineCap {

     //kCGLineCapButt, 默认值

     //kCGLineCapRound, 圆角

     //kCGLineCapSquare 方角

     //};


        CGContextSetLineCap(ctx, kCGLineCapSquare);



        // 3. 渲染

        CGContextStrokePath(ctx);

    }

     */


    9> 设置转折点样式

    /** 參考代码:

     

     void test10()

     {

         // 1. 获取上下文对象

         CGContextRef ctx = UIGraphicsGetCurrentContext();

         

         // 2. 绘制路径

         // 2.1 移动到起点

         CGContextMoveToPoint(ctx, 20, 20);

         

         // 2.2 加入一条线段

         CGContextAddLineToPoint(ctx, 100, 100);

         // 2.3 再加入一条线段

         CGContextAddLineToPoint(ctx, 150, 50);

         

         

         // 2.3 设置颜色

         [[UIColor redColor] set];

         

         

         // 2.4 设置线段宽度

         CGContextSetLineWidth(ctx, 15);

         

         // 2.5 设置线段头尾部样式

         CGContextSetLineCap(ctx, kCGLineCapRound);

         // 2.6 设置转折点样式

         CGContextSetLineJoin(ctx, kCGLineJoinBevel);

         

         

         // 3. 渲染

         CGContextStrokePath(ctx);

     }


     

     */




    * 椭圆

    1> 椭圆

    /** 參考代码: 思路, 圆事实上就是一个在在矩形中的图形。

     // 绘制圆和椭圆

     void test()

     {

         // 1. 获取上下文

         CGContextRef ctx = UIGraphicsGetCurrentContext();

         

         // 2. 绘制图形

         // 椭圆

         CGContextAddEllipseInRect(ctx, CGRectMake(10, 20, 150, 100));

         //

         CGContextAddEllipseInRect(ctx, CGRectMake(30, 50, 100, 100));

         

         // 3. 渲染

         CGContextStrokePath(ctx);

     }

     */


    2> 绘制圆环:

    * 思路1: 在画圆的时候, 设置线宽就可以。CGContextSetLineWidth(ctx, 20);

    * 思路2: 画两个嵌套的圆




    3> 画不同的圆弧

    * 画上面半个圆弧

    * 画以下半个圆弧

    * 画右下角的1/4圆弧

    * 左側半圆弧

    * 右側半圆弧

    * 左下角的1/4的圆弧

    * 画一个圆

    /** 參考代码:

     // 画不同的圆弧

     void test2()

     {

         // 1. 获取上下文

         CGContextRef ctx = UIGraphicsGetCurrentContext();

         

         // 2. 绘制图形

         // 画圆弧

         // ios 系统中坐标系刚好是反的所以指定了1(顺时针)反而效果是"逆时针"

         //CGContextAddArc(ctx, 100, 100, 50, 0, M_PI, 0);

         //CGContextAddArc(ctx, 100, 100, 50, 0, M_PI * 0.5, 0);

         //CGContextAddArc(ctx, 100, 100, 50, -M_PI_2, M_PI_2, 0);

         // 绘制左下角的1/4的圆弧

         //CGContextAddArc(ctx, 100, 100, 50, M_PI, M_PI_2, 1);

         // 画一个圆

         //CGContextAddArc(ctx, 100, 100, 50, 0, M_PI * 2, 1);

         

         // 3. 渲染

         CGContextStrokePath(ctx);

     }


     */


    4> 演示

    /** 參考代码:



     - (void)drawRect:(CGRect)rect {

     

         // 1. 获取上下文

         CGContextRef ctx = UIGraphicsGetCurrentContext();

         

         // 2. 绘制图形

         // 绘制左下角的1/4的圆弧

         CGContextAddArc(ctx, 100, 100, 50, M_PI, M_PI_2, 1);

         

         // 3. 渲染

         CGContextFillPath(ctx);

     }


     */


    5> 画一个左下角1/4 的实心圆

    /** 參考代码:

     

     - (void)drawRect:(CGRect)rect {

     

         // 1. 获取上下文

         CGContextRef ctx = UIGraphicsGetCurrentContext();

         

         // 2. 绘制图形

         // 绘制左下角的1/4的圆弧

         CGContextAddArc(ctx, 100, 100, 50, M_PI, M_PI_2, 1);

         // 加入一根线

         CGContextAddLineToPoint(ctx, 100, 100);

         // 关闭路径

         CGContextClosePath(ctx);

         

         // 3. 渲染

         CGContextFillPath(ctx);

     }

     

     */




    * 文字绘制(通过OC 来绘制图形)

    1> 绘制一段文字(思路: 直接使用 OC 的方法, 无需手动获取上下文对象)

    /** 參考代码:

     

     - (void)drawRect:(CGRect)rect {

         NSString *str = @"哈哈, 黑马程序猿 iOS学院。";

     

         NSDictionary *attrs = @{

             NSForegroundColorAttributeName : [UIColor redColor],

             NSFontAttributeName : [UIFont systemFontOfSize:20]

         };

     

         [str drawAtPoint:CGPointMake(30, 50) withAttributes:attrs];

     }

     */



    2> 绘制一段文字到一个指定的区域

    * 思路: 调用字符串的 drawInRect: 方法.

    /** 參考代码:

     

     - (void)drawRect:(CGRect)rect {

     

     

         // 1. 绘制文字

         NSString *str = @"哈哈, 黑马程序猿 iOS

    ";

         

         NSDictionary *attrs = @{

         NSForegroundColorAttributeName : [UIColor redColor],

         NSFontAttributeName : [UIFont systemFontOfSize:20]

         };

         

         [str drawInRect:CGRectMake(20, 20, 50, 250) withAttributes:attrs];

         

         

         

         // 1. 获取上下文

         CGContextRef ctx = UIGraphicsGetCurrentContext();

         // 2. 把矩形画出来

         CGContextAddRect(ctx,CGRectMake(20, 20, 50, 250));

         

         // 3. 渲染

         CGContextStrokePath(ctx);

     }

     

     */







    * 图片绘制(通过OC 来绘制图形)

    1> 绘制一张图片到 UIView 上。

    * 思路: 通过 OC 的方法来实现。

    /** 參考代码:

     - (void)drawRect:(CGRect)rect {

         // 1. 获取图片

         UIImage *img = [UIImage imageNamed:@"dst2"];

         // 2. 把图片画到当前的 view

         [img drawAtPoint:CGPointMake(0, 0)];

     }

     */


    2. 在指定的矩形中绘制图片(会自己主动拉伸)

    /** 參考代码:

     - (void)drawRect:(CGRect)rect {

     

         // 1. 获取图片

         UIImage *img = [UIImage imageNamed:@"dst2"];

         // 2. 把图片画到当前的 view

         [img drawInRect:CGRectMake(0, 0, 150, 150)];

     

     }

     */



    3. 画格子花纹效果(pattern), 思路: 调用drawAsPatternInRect:方法

    /** 參考代码:

     - (void)drawRect:(CGRect)rect {

         // 1. 获取图片

         UIImage *img = [UIImage imageNamed:@"abc"];

     

         // 2. 把图片画到当前的 view

         [img drawAsPatternInRect:self.bounds];

     

         // 3. 在右下角显示文字

         NSString *str = @"@传智播客 ios 学院";

         NSDictionary *attrs = @{

         NSForegroundColorAttributeName : [UIColor redColor],

         NSFontAttributeName : [UIFont systemFontOfSize:20]

         };

         

         [ str drawInRect:CGRectMake(0, 100, 200, 30) withAttributes:attrs];

     }

     */







    * 在指定的区域画一张图片, 然后再在指定的区域画一些文字(水印)

    /** 參考代码:

     

     - (void)drawRect:(CGRect)rect {

     // Drawing code

     

     // 在指定的区域内画一张图片

     UIImage *img = [UIImage imageNamed:@"dst2"];

     [img drawInRect:self.bounds];

     

     

     // 在指定的区域画一些文字

     NSString *str = @"传智播客 iOS 学院。

    ";

     [str drawInRect:CGRectMake(10, 400, 200, 30) withAttributes:nil];

     

     }

     */




    * 图形上下文栈

    1> 画两根线, 设置线的颜色、宽度、头尾的样式 LineCap

    2> 要求, 第二根线不具有第一根线的样式。

    3> 解决, 在画第一根线之前先保存"画图上下文栈", 在画第二根线的时候再恢复画图上下文栈

    CGContextSaveGState(ctx);// 保存ctx这个画图上下文对象

    CGContextRestoreGState(ctx); // 恢复 ctx这个图形上下文




    * 矩阵操作

    1> 总体旋转、总体缩放

    * 思路: 随便在一个 UIView 上画一些图形(线段、矩形、圆等)

    /** 參考代码:

     

     - (void)drawRect:(CGRect)rect {

         // Drawing code

         // 1. 获取上下文

         CGContextRef ctx = UIGraphicsGetCurrentContext();

         

         //======================= 矩阵操作 ============================

         // 1.1 旋转

         CGContextRotateCTM(ctx, M_PI_4 * 0.5);

         // 1.2 缩放

         CGContextScaleCTM(ctx, 0.5, 0.5);

         //======================= 矩阵操作 ============================

         

         // 2. 绘制一些图形

         CGContextMoveToPoint(ctx, 10, 10);

         CGContextAddLineToPoint(ctx, 100, 100);

         CGContextAddEllipseInRect(ctx, CGRectMake(130, 150, 100, 100));

         CGContextAddRect(ctx, CGRectMake(70, 90, 100, 80));

         

         

         // 3. 渲染

         CGContextStrokePath(ctx);

     

     }

     

     */




    2> 最后画的那个图形不要矩阵操作

    * 思路: 在绘制不论什么图形前保存上下文, 在绘制最后一个图形前恢复上下文

    /** 參考代码:

     - (void)drawRect:(CGRect)rect {

         // Drawing code

         // 1. 获取上下文

         CGContextRef ctx = UIGraphicsGetCurrentContext();

         

         // 保存上下文

         CGContextSaveGState(ctx);

         

         //======================= 矩阵操作 ============================

         // 1.1 旋转

         CGContextRotateCTM(ctx, M_PI_4 * 0.5);

         // 1.2 缩放

         CGContextScaleCTM(ctx, 0.5, 0.5);

         //======================= 矩阵操作 ============================

         

         // 2. 绘制一些图形

         CGContextMoveToPoint(ctx, 10, 10);

         CGContextAddLineToPoint(ctx, 100, 100);

         CGContextAddEllipseInRect(ctx, CGRectMake(130, 150, 100, 100));

         

         

         // 恢复上下文

         CGContextRestoreGState(ctx);

         

         CGContextAddRect(ctx, CGRectMake(70, 90, 100, 80));

         

         

         // 3. 渲染

         CGContextStrokePath(ctx);

     

     }

     

     */


    * 图片裁剪

    1> 把一个图片裁剪成圆形

    ** 思路:

    - UIView 上绘制一个25 * 25的圆

    - 裁剪上下文

    载入图片, 把图片绘制到 "上下文" , 就自己主动实现了裁剪了


    /** 參考代码:

     

     - (void)drawRect:(CGRect)rect {

         // Drawing code

         CGContextRef ctx = UIGraphicsGetCurrentContext();

         

         // 1. 画圆,这里最好使用 Ellipse 来绘制圆(画圆和绘图片都从0,0点開始)。

         CGContextAddArc(ctx, 100, 100, 90, 0, M_PI * 2, 1);

         

         // 2. 裁剪上下文, 注意裁剪完成就仅仅能在裁剪好的区域内画东西了, 超出的地方无法绘制图形。

         CGContextClip(ctx);

         

         // 3. 把图片绘制上去

         UIImage *img = [UIImage imageNamed:@"dst2"];

         [img drawAtPoint:CGPointMake(0, 0)];

     }

     

     */



    * 重绘案例: 调整 slider 滑动条, 同一时候改变圆的大小

    1> 思路: 让绘制圆时, 半径随着 slider 的变化而变化

    * setNeedsDisplay 方法会把之前的内容都清除掉, 然后再重绘。

    * setNeedsDisplayInRect:<#(CGRect)#>局部刷新

    /** 參考代码:

     

     - (void)setRadius:(CGFloat)radius

     {

         _radius = radius;

         [self setNeedsDisplay];

     }

     


     - (void)drawRect:(CGRect)rect {

         // Drawing code

         CGContextRef ctx = UIGraphicsGetCurrentContext();

         

         CGContextAddArc(ctx, 100, 100, self.radius, 0, M_PI * 2, 1);

         

         CGContextFillPath(ctx);

     

     }

     

     */


    3.模仿UIImageView

    * 思路:

    1> 演示 UIImageView 的基本使用方法

    2> 自己定义一个类继承自 UIView, 加入一个 image 属性


    /** 參考代码:

     // 1. 控制器

     - (void)viewDidLoad {

     [super viewDidLoad];

     // Do any additional setup after loading the view, typically from a nib.

     MyImageView *imgView =[[MyImageView alloc] init];

     imgView.image = [UIImage imageNamed:@"dst2"];

     imgView.frame = CGRectMake(30, 30, 100, 100);

     [self.view addSubview:imgView];

     

     self.myImgView = imgView;

     

     }

     

     - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

     {

     self.myImgView.image = [UIImage imageNamed:@"snow"];

     }


     

     

     // 2. 自己定义 view

     - (void)setImage:(UIImage *)image

     {

     _image = image;

     [self setNeedsDisplay];

     }

     

     // Only override drawRect: if you perform custom drawing.

     // An empty implementation adversely affects performance during animation.

     - (void)drawRect:(CGRect)rect {

     // Drawing code

     [self.image drawAtPoint:CGPointZero];

     }


     

     

     */


  • 相关阅读:
    sort函数详解
    C++重载运算符的规则详解
    poj3061-subsequence
    员工管理系统 :练习
    Jdbc 模拟登陆系统的练习
    有关String 的常用方法
    浅谈希尔排序-----摘录
    简单选择排序
    typedef 和define 的区别
    写博客的理由
  • 原文地址:https://www.cnblogs.com/yfceshi/p/7345673.html
Copyright © 2011-2022 走看看