zoukankan      html  css  js  c++  java
  • core graphics path

    当UIKit无法满足画图需求的时候。就须要用到Core Graphics API。当中最普遍的就是path。

    一些重要的概念

    graphics context

    能够理解成canvas。在ios里相应CGContextRef类型,拿到它的方法是调用这个函数:

    UIGraphicsGetCurrentContext()

    graphics context有非常多种,能够分别将图形绘制到bitmap,PDF,UIView里。最常见的当然就是往UIView里绘制,做法就是覆盖UIView的drawRect:方法,然后调用上面这个函数,就得到了针对UIView的graphics context。

    因为初始化的工作UIKit已经完毕了,所以开发人员能够立马绘制图形,不须要额外配置

    标准的quartz 2D,context的坐标系原点在左下角。可是UIKit已经自己主动转换了。原点移到了左上角,与UIView的坐标系保持一致

    graphics state

    保存绘制參数,比方线条的粗细。颜色,样式等等,完整的參数列表能够看apple的官方文档。graphics state是一个stack数据结构,能够用下面函数运行push和pop的操作:

    CGContextSaveGState()
    CGContextRestoreGState()

    假设不须要暂存state状态后面继续使用的话,能够直接调用CGContextSetXXX函数,即时设置状态,比方:

    CGContextSetLineWidth()
    CGContextSetStrokeColorWithColor()

    path的2段式绘制

    绘制path分2个阶段。各自是path创建和path画图

    创建path用到的函数有非常多,比方addLineToPoint,addRect。addArc等。这些函数仅仅是创建了path和它的subpaths。并不会实际画到graphics context上

    创建path之后,须要调用fill和stroke函数。把当前的path画出来。绘制的函数包含:

    CGContextStrokePath()
    CGContextFillPath()
    CGContextDrawPath()

    strokePath和fillPath都属于fluent function。假设须要同一时候stroke和fill。那么应该调用第三个函数。然后将绘制mode设置为既stroke又fill

    刚開始学习的人一个常见的问题是。创建了一段path之后。先调用strokePath(),再调用fillPath(),为什么fill没有生效。

    由于不管是fill还是stroke。调用之后都flash了缓冲区,之前已经绘制好的path就结束了。所以后调用的函数就不会生效。

    正确的方法是调用drawPath

    一次仅仅能绘制一个path

    创建path通常是从调用这个函数開始:

    CGContextBeginPath()

    调用这个函数,标识着開始创建一个path。可是假设仅仅有一个path,或者paint之后再次创建path,事实上这个函数也不须要调用。

    一般这个函数是和CGPathRef配合使用的,仅仅有须要暂存一个path。兴许继续使用的场景下,才须要调用这个函数

    可是须要了解“一次仅仅能绘制一个path”这个概念。比方以下的代码:

    CGContextMoveToPoint(context, 100, 100);
    CGContextAddLineToPoint(context, 200, 100);
    
    CGContextBeginPath();
    
    CGContextMoveToPoint(context, 100, 200);
    CGContextAddLineToPoint(context, 200, 200);
    
    CGContextStrokePath(context);

    先创建了一个path。然后又创建了第2个path,最后调用stroke方法。仅仅有第2个path会被画出来。由于graphics context每次仅仅会画出“当前的”path。

    上面的代码。第一个path永远也绘制不出来,等于是丢失了

    subpath

    可是这并不意味着path不能绘制复杂的图形。由于一个path能够包括随意subpath。调用fillPath,strokePath,beginPath函数。都会開始一个新的path。

    可是在调用之前,能够加入随意个subpath,比方addLineToPoint,addRect等函数。都会加入subpath到当前的path中,下一次paint的时候,会把全部的subpath都画出来

    path闭合

    graphics context会始终维护一个current point。创建path的第一步。就须要调用

    CGContextMoveToPoint()

    这样context就获得了第一个当前点,然后当调用addLineToPoint时,current point就会自己主动移动,从而绘制出连续的线条。假设想要画不连续的线条。就再次调用CGContextMoveToPoint,改变current point的位置。

    这种方法创建的是subpath。不会创建新的path

    创建若干line之后,能够调用CGContextClosePath,创建出一个封闭的区域,对兴许的stroke和fill都有效

    抗锯齿

    调用以下的2个函数,能够设置绘制的图形有抗锯齿效果:

    CGContextSetShouldAntialias(context, YES);
    CGContextSetAllowsAntialiasing(context, YES);


  • 相关阅读:
    RubyConf的podcast
    一篇很好的英语学习文章:一个孤独而封闭世界――英语口语
    新浪和搜狐的读书频道
    新想法:个性化的RSS
    代码搜索:Koders
    我看到的Web 2.0: 自组织的大众化参与
    土豆网的后舍男孩挺搞笑的
    可以给pdf加批注的软件VeryPDF PDF Editor
    张海迪写的描写英语学习经验的书《美丽的英语》
    Fowler出来推荐Rake了(基于Ruby的build工具)
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/5147897.html
Copyright © 2011-2022 走看看