• 任意多边形(不仅仅是一个矩形)
    • 斜线或曲线
    • 文本
    • 渐变

        举个例子,清单13.1 展示了一个基本的画线应用。这个应用将用户的触摸手势转换成一个上的点,然后绘制成视图。我们在一个UIView子类DrawingView中实现了所有的绘制逻辑,这个情况下我们没有用上view controller。但是如果你喜欢你可以在view controller中实现触摸事件处理。图13.1是代码运行结果。

    清单13.1 用Core Graphics实现一个简单的绘图应用

    图13.1 用Core Graphics做一个简单的『素描』

        这样实现的问题在于,我们画得越多,程序就会越慢。因为每次移动手指的时候都会重绘整个贝塞尔路径(UIBezierPath),随着路径越来越复杂,每次重绘的工作就会增加,直接导致了帧数的下降。看来我们需要一个更好的方法了。

        如果稍微将之前的代码变动一下,用CAShapeLayer替代Core Graphics,性能就会得到提高(见清单13.2).虽然随着路径复杂性的增加,绘制性能依然会下降,但是只有当非常非常浮躁的绘制时才会感到明显的帧率差异。

    清单13.2 用CAShapeLayer重新实现绘图应用

    1. #import "DrawingView.h"
    2. #import <QuartzCore/QuartzCore.h>
    3. @interface DrawingView ()
    4. @property (nonatomic, strong) UIBezierPath *path;
    5. @end
    6. @implementation DrawingView
    7. {
    8. //this makes our view create a CAShapeLayer
    9. return [CAShapeLayer class];
    10. }
    11. - (void)awakeFromNib
    12. {
    13. //create a mutable path
    14. self.path = [[UIBezierPath alloc] init];
    15. //configure the layer
    16. CAShapeLayer *shapeLayer = (CAShapeLayer *)self.layer;
    17. shapeLayer.strokeColor = [UIColor redColor].CGColor;
    18. shapeLayer.fillColor = [UIColor clearColor].CGColor;
    19. shapeLayer.lineJoin = kCALineJoinRound;
    20. shapeLayer.lineCap = kCALineCapRound;
    21. shapeLayer.lineWidth = 5;
    22. }
    23. - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    24. //get the starting point
    25. CGPoint point = [[touches anyObject] locationInView:self];
    26. //move the path drawing cursor to the starting point
    27. [self.path moveToPoint:point];
    28. }
    29. - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
    30. {
    31. //get the current point
    32. CGPoint point = [[touches anyObject] locationInView:self];
    33. //add a new line segment to our path
    34. [self.path addLineToPoint:point];
    35. //update the layer with a copy of the path
    36. ((CAShapeLayer *)self.layer).path = self.path.CGPath;