IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形

第五章:Transforms

Affine Transforms
CGAffineTransform是二维的
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第1张图片

IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第2张图片

Creating a CGAffineTransform

主要有三种变化方法
旋转:
CGAffineTransformMakeRotation(CGFloat angle)
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第3张图片


缩放:
CGAffineTransformMakeScale(CGFloat sx, CGFloat sy)
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第4张图片


移动:
CGAffineTransformMakeTranslation(CGFloat tx, CGFloat ty)
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第5张图片
例子5.1 CGAffineTransformMakeRotation

源码在这里下载:http://www.informit.com/title/9780133440751

[objc]  view plain copy print ?
  1. @interface ViewController ()  
  2.   
  3. @property (nonatomic, weak) IBOutlet UIView *layerView;  
  4.   
  5. @end  
  6.   
  7. @implementation ViewController  
  8.   
  9. - (void)viewDidLoad  
  10. {  
  11.     [super viewDidLoad];  
  12.       
  13.     //rotate the layer 45 degrees  
  14.     CGAffineTransform transform = CGAffineTransformMakeRotation(M_PI_4);  
  15.     self.layerView.layer.affineTransform = transform;  
  16. }  
  17.   
  18. @end  
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第6张图片

修改 CGAffineTransformMakeScale
[objc]  view plain copy print ?
  1. - (void)viewDidLoad  
  2. {  
  3.     [super viewDidLoad];  
  4.       
  5.     //rotate the layer 45 degrees  
  6.     CGAffineTransform transform = CGAffineTransformMakeScale(0.50.5);  
  7.     self.layerView.layer.affineTransform = transform;  
  8. }  
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第7张图片

修改   CGAffineTransformMakeTranslation
[objc]  view plain copy print ?
  1. - (void)viewDidLoad  
  2. {  
  3.     [super viewDidLoad];  
  4.       
  5.     //rotate the layer 45 degrees  
  6.     CGAffineTransform transform = CGAffineTransformMakeTranslation(-50.030.0);  
  7.     self.layerView.layer.affineTransform = transform;  
  8. }  
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第8张图片



Combining Transforms

方法1:使用CGAffineTransformConcat

继续修改例子5.1
[objc]  view plain copy print ?
  1. - (void)viewDidLoad  
  2. {  
  3.     [super viewDidLoad];  
  4.       
  5.     //rotate the layer 45 degrees  
  6.     CGAffineTransform transform1 = CGAffineTransformMakeRotation(M_PI_4);  
  7.     CGAffineTransform transform2 = CGAffineTransformMakeScale(0.50.5);  
  8.     CGAffineTransform transform = CGAffineTransformConcat(transform1, transform2);  
  9.     self.layerView.layer.affineTransform = transform;  
  10. }  
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第9张图片

方法2:
CGAffineTransformRotate(CGAffineTransform t, CGFloat angle)
CGAffineTransformScale(CGAffineTransform t, CGFloat sx, CGFloat sy)
CGAffineTransformTranslate(CGAffineTransform t, CGFloat tx, CGFloat ty)
和前面的CGAffineTransformMakeRotation函数相同,也可以混用
CGAffineTransform t可以使用CGAffineTransformIdentity函数初始化

例子5.2
[objc]  view plain copy print ?
  1. @interface ViewController ()  
  2.   
  3. @property (nonatomic, weak) IBOutlet UIView *layerView;  
  4.   
  5. @end  
  6.   
  7. @implementation ViewController  
  8.   
  9. - (void)viewDidLoad  
  10. {  
  11.     [super viewDidLoad];  
  12.       
  13.     //create a new transform  
  14.     CGAffineTransform transform = CGAffineTransformIdentity;  
  15.       
  16.     //scale by 50%  
  17.     transform = CGAffineTransformScale(transform, 0.50.5);  
  18.       
  19.     //rotate by 30 degrees  
  20.     transform = CGAffineTransformRotate(transform, M_PI / 180.0 * 30.0);  
  21.       
  22.     //translate by 200 points  
  23.     transform = CGAffineTransformTranslate(transform, 2000);  
  24.       
  25.     //apply transform to layer  
  26.     self.layerView.layer.affineTransform = transform;  
  27. }  
  28.   
  29. @end  
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第10张图片


下面记几个特殊值
1. 首先要知道函数 CGAffineTransformIdentity 初始化的结果
          IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第11张图片

2. 左右翻转
    CGAffineTransformMake(-1,0,0,1,0,0);
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第12张图片

3. 以右边为轴向右翻转
    CGAffineTransformMake(-1,0,0,1,self.layerView.frame.size.width,0);
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第13张图片

4. 上下翻转

    CGAffineTransformMake(1,0,0, -1,0,0);

IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第14张图片

5. 以底边为轴向下翻转
    CGAffineTransformMake(1,0,0, -1,0,self.layerView.frame.size.height);
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第15张图片

6. 转180°
    CGAffineTransformMake(-1,0,0, -1,0,0);
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第16张图片

7. 例子5.3,向右斜拉
    CGAffineTransformMake(1,0, -1,1,0,0);
代码:
[objc]  view plain copy print ?
  1. @interface ViewController ()  
  2.   
  3. @property (nonatomic, weak) IBOutlet UIView *layerView;  
  4.   
  5. @end  
  6.   
  7. @implementation ViewController  
  8.   
  9. CGAffineTransform CGAffineTransformMakeShear(CGFloat x, CGFloat y)  
  10. {  
  11.     CGAffineTransform transform = CGAffineTransformIdentity;  
  12.     transform.c = -x;  
  13.     transform.b = y;  
  14.     return transform;  
  15. }  
  16.   
  17. - (void)viewDidLoad  
  18. {  
  19.     [super viewDidLoad];  
  20.       
  21.     //shear the layer at a 45-degree angle  
  22.     self.layerView.layer.affineTransform = CGAffineTransformMakeShear(10);  
  23. }  
  24.   
  25. @end  
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第17张图片

8. 例子5.3,向左斜拉
    CGAffineTransformMake(10,1100);
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第18张图片



3D Transforms

类似CGAffineTransform,CATransform3D是三维的
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第19张图片

CATransform3D又是一个结构。他有自己的一个公式,可以进行套用。

struct CATransform3D

{

    CGFloat     m11(x缩放),    m12(y切变),    m13(旋转),     m14( );

    CGFloat     m21(x切变),    m22(y缩放),    m23( ),           m24( );

    CGFloat     m31(旋转),      m32( ),           m33( ),            m34(透视效果,要操作的这个对象要有旋转的角度,否则没有效果。正直/负值都有意义);

    CGFloat     m41(x平移),    m42(y平移),    m43(z平移),    m44( );

};



同样有三种变换方法

旋转:
CATransform3DMakeRotation(CGFloat angle, CGFloat x, CGFloat y, CGFloat z)
首先要先清楚x,y,z是什么
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第20张图片
{x, y, z}组成的向量就是旋转要使用的轴,angle是旋转角度
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第21张图片

例:原图 

            IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第22张图片 

       向X轴旋转45度。                               Y轴旋转45度。                         Z轴旋转45度。

    IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第23张图片  IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第24张图片  IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第25张图片

 X轴,Y轴都旋转45度,就是沿着对角线旋转。

IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第26张图片


缩放:
CATransform3DMakeScale(CGFloat sx, CGFloat sy, CGFloat sz)

sxX轴缩放,代表一个缩放比例,一般都是0 ---1之间的数字。

syY轴缩放。

sz:整体比例变换时,也就是m11(sx) == m22(sy)时,若m33(sz)>1,图形整体缩小,

        若< m33(sz) 1,图形整体放大,

        若m33(sz) 0,发生关于原点的对称等比变换。


sx = 1sy =1时。如图:

IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第27张图片

sx = 0.5sy =0.5时。如图:

IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第28张图片


变换:
CATransform3DMakeTranslation(Gloat tx, CGFloat ty, CGFloat tz)

t' = [1 0 0 0; 0 1 0 0; 0 0 1 0; tx ty tz 1]

1    0    0    0

0    1    0    0

0    0    1    0

tx   ty    tz   1

竖起来看对应前面的数据结构就很明显了。


txX轴偏移位置,往下为正数。

tyY轴偏移位置,往右为正数。

tzZ轴偏移位置,往外为正数。



可以通过直接修改数据结构,来设置变换效果

struct CATransform3D

{

    CGFloat m11, m12, m13, m14

    CGFloat m21, m22, m23, m24

    CGFloat m31, m32, m33, m34

    CGFloat m41, m42, m43, m44

}

[objc]  view plain copy print ?
  1. CATransform3D transform = CATransform3DMakeRotation(M_PI_4010);  
  2. transform.m11 = 2;  

或者修改键值

[objc]  view plain copy print ?
  1. [myLayer setValue:[NSNumber numberWithInt:0] forKeyPath:@"transform.rotation.x"];  


IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第29张图片

例子5.4
[objc]  view plain copy print ?
  1. @interface ViewController ()  
  2.   
  3. @property (nonatomic, weak) IBOutlet UIView *layerView;  
  4.   
  5. @end  
  6.   
  7. @implementation ViewController  
  8.   
  9. - (void)viewDidLoad  
  10. {  
  11.     [super viewDidLoad];  
  12.       
  13.     //rotate the layer 45 degrees along the Y axis  
  14.     CATransform3D transform = CATransform3DMakeRotation(M_PI_4010);  
  15.     self.layerView.layer.transform = transform;  
  16. }  
  17.   
  18. @end  
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第30张图片

修改例子5.4,修改自http://lepetit-prince.net/ios/?p=451

[objc]  view plain copy print ?
  1. #import "ViewController.h"  
  2. #import <QuartzCore/QuartzCore.h>  
  3.   
  4. @interface ViewController ()  
  5. {  
  6.     BOOL front;  
  7. }  
  8.   
  9. @property (nonatomic, weak) IBOutlet UIView *layerView;  
  10.   
  11. @end  
  12.   
  13.   
  14. @implementation ViewController  
  15.   
  16. - (void)viewDidLoad  
  17. {  
  18.     [super viewDidLoad];  
  19.   
  20.     front = YES;  
  21.   
  22.     self.layerView.layer.contents = (__bridge id)([UIImage imageNamed:@"front.png"].CGImage);  
  23. }  
  24.   
  25. - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event  
  26. {  
  27.     [UIView animateWithDuration:0.5 animations:^{  
  28.         self.layerView.layer.transform = CATransform3DMakeRotation(M_PI * 0.50.0f1.0f0.0f);  
  29.     } completion:^(BOOL finished) {  
  30.         self.layerView.layer.transform = CATransform3DMakeRotation(M_PI * 1.50.0f1.0f0.0f);  
  31.   
  32.         self.layerView.layer.contents = front ? (__bridge id)([UIImage imageNamed:@"back.png"].CGImage) : (__bridge id)([UIImage imageNamed:@"front.png"].CGImage);  
  33.   
  34.         [UIView animateWithDuration:0.5 animations:^{  
  35.             self.layerView.layer.transform = CATransform3DMakeRotation(M_PI * 20.0f1.0f0.0f);  
  36.         } completion:^(BOOL finished) {  
  37.             front = !front;  
  38.         }];  
  39.     }];  
  40. }  
  41.   
  42. @end  
资源文件  front.png    back.png
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第31张图片


Perspective Projection

前面提到过m34(透视效果,要操作的这个对象要有旋转的角度,否则没有效果。正直/负值都有意义)

例子5.5
[objc]  view plain copy print ?
  1. @interface ViewController ()  
  2.   
  3. @property (nonatomic, weak) IBOutlet UIView *layerView;  
  4.   
  5. @end  
  6.   
  7. @implementation ViewController  
  8.   
  9. - (void)viewDidLoad  
  10. {  
  11.     [super viewDidLoad];  
  12.       
  13.     //create a new transform  
  14.     CATransform3D transform = CATransform3DIdentity;  
  15.       
  16.     //apply perspective  
  17.     transform.m34 = - 1.0 / 500.0;  
  18.       
  19.     //rotate by 45 degrees along the Y axis  
  20.     transform = CATransform3DRotate(transform, M_PI_4010);  
  21.       
  22.     //apply to layer  
  23.     self.layerView.layer.transform = transform;  
  24. }  
  25.   
  26. @end  
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第32张图片

如果修改注释掉旋转,看看会有什么结果
[objc]  view plain copy print ?
  1. //rotate by 45 degrees along the Y axis  
  2. //transform = CATransform3DRotate(transform, M_PI_4, 0, 1, 0);  

例子是用的透视场景是±1.0/d,d镜头到景物的距离,取值500~1000效果最好,±代表方向


The Vanishing Point

当景物慢慢远离镜头时,随着越来越小最终聚集到一点就是Vanishing Point(灭点)

通常情况灭点是在视图的正中心,或者在包含所有景物范围的中心。
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第33张图片

Core Animation把灭点定义在anchorPoint,所以在变换前需要确定anchorPoint,
尤其需要注意,3D变换时最好确保同一视图内的所有layey有相同的灭点


The sublayerTransform Property

如果你有多个View或Layer有相同的3D变换,就可以使用 sublayerTransform,

sublayerTransform也是CATransform3D,只有sublayers才会响应。

默认值是Identity Transform(CATransform3DIdentity)


例子5.6
[objc]  view plain copy print ?
  1. @interface ViewController ()  
  2.   
  3. @property (nonatomic, weak) IBOutlet UIView *containerView;  
  4. @property (nonatomic, weak) IBOutlet UIView *layerView1;  
  5. @property (nonatomic, weak) IBOutlet UIView *layerView2;  
  6.   
  7. @end  
  8.   
  9. @implementation ViewController  
  10.   
  11. - (void)viewDidLoad  
  12. {  
  13.     [super viewDidLoad];  
  14.       
  15.     //apply perspective transform to container  
  16.     CATransform3D perspective = CATransform3DIdentity;  
  17.     perspective.m34 = - 1.0 / 500.0;  
  18.     self.containerView.layer.sublayerTransform = perspective;  
  19.       
  20.     //rotate layerView1 by 45 degrees along the Y axis  
  21.     CATransform3D transform1 = CATransform3DMakeRotation(M_PI_4010);  
  22.     self.layerView1.layer.transform = transform1;  
  23.       
  24.     //rotate layerView2 by 45 degrees along the Y axis  
  25.     CATransform3D transform2 = CATransform3DMakeRotation(-M_PI_4010);  
  26.     self.layerView2.layer.transform = transform2;  
  27. }  
  28.   
  29. @end  
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第34张图片

我们挪动一下xib里的图片位置:
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第35张图片
再看结果
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第36张图片

恢复xib文件,并修改代码
[objc]  view plain copy print ?
  1. - (void)viewDidLoad  
  2. {  
  3.     [super viewDidLoad];  
  4.       
  5.     //apply perspective transform to container  
  6. //    CATransform3D perspective = CATransform3DIdentity;  
  7. //    perspective.m34 = - 1.0 / 500.0;  
  8. //    self.containerView.layer.sublayerTransform = perspective;  
  9.   
  10.     //apply perspective  
  11.     CATransform3D transform1 = CATransform3DIdentity;  
  12.     transform1.m34 = - 1.0 / 500.0;  
  13.     transform1 = CATransform3DRotate(transform1, M_PI_4010);  
  14.     self.layerView1.layer.transform = transform1;  
  15.       
  16.     //rotate layerView2 by 45 degrees along the Y axis  
  17.     CATransform3D transform2 = CATransform3DIdentity;  
  18.     transform2.m34 = - 1.0 / 500.0;  
  19.     transform2 = CATransform3DRotate(transform2, -M_PI_4010);  
  20.     self.layerView2.layer.transform = transform2;  
  21. }  
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第37张图片

结果和最初一样,但再次修改xib文件,挪动图片看 结果,比较未改代码时的效果
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第38张图片

大家发现设置 sublayerTransform的好处了吗

1. 可以一次设置所有subLayer的变换效果
2. Vanishing Point(灭点)被同时设置在container layer即父图层的中心,这就意味着无论你怎么
    修改subLayer的position或frame,它们都会保持一个相同的灭点。


Backfaces

例子5.4,我们设置的是旋转M_PI_4(45°),改为M_PI(180°)
[objc]  view plain copy print ?
  1. - (void)viewDidLoad  
  2. {  
  3.     [super viewDidLoad];  
  4.       
  5.     //rotate the layer 45 degrees along the Y axis  
  6.     CATransform3D transform = CATransform3DMakeRotation(M_PI, 010);  
  7.     self.layerView.layer.transform = transform;  
  8. }  
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第39张图片

翻到了layer背面,显示的是原图像的镜像图。由此可见layer是双面的,并且两面都被描绘了。
因此我们会想到,为什么要浪费GPU去描绘我们看不见的部分呢。CALayer的另外一个属性
doubleSided可以解决这个问题。
在刚才修改过的例子5.4的代码中增加doubleSided设置
[objc]  view plain copy print ?
  1. - (void)viewDidLoad  
  2. {  
  3.     [super viewDidLoad];  
  4.       
  5.     //rotate the layer 45 degrees along the Y axis  
  6.     CATransform3D transform = CATransform3DMakeRotation(M_PI, 010);  
  7.     self.layerView.layer.transform = transform;  
  8.     self.layerView.layer.doubleSided = NO;  
  9. }  
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第40张图片
图像没有了



Layer Flattening
自己看例子吧,例子5.7和5.8


Solid Objects
也自己看例子吧,例子5.9和5.10


第六章: Specialized Layers

类别

用途

CAEmitterLayer

用于实现基于Core Animation粒子发射系统。发射器层对象控制粒子的生成和起源

CAGradientLayer

用于绘制一个颜色渐变填充图层的形状(所有圆角矩形边界内的部分)

CAEAGLLayer/CAOpenGLLayer

用于设置需要使用OpenGL ES(iOS)或OpenGL(OS X)绘制的内容与内容储备。

CAReplicatorLayer

当你想自动生成一个或多个子层的拷贝。复制器为你生成拷贝并使用你指定的属性值以修改复制品的外观和属性。

CAScrollLayer

用于管理由多个子区域组成的大的可滚动区域

CAShaperLayer

用于绘制三次贝塞尔曲线。CAShaperLayer对绘制基于路径的形状非常有帮助。因为CAShaperLayer总是生成一个最新的路径。而如果将路径画在图层储备中,一旦图层被缩放,形状就变形了。

CATextLayer

用于渲染一个无格式或属性文本字符

CATransformLayer

用于渲染一个真3D的图层层级。而不是由其他图层类实现的2D图层层级。

QCCompositionLayer

用于渲染一个Quartz组件元素(仅在OS X中有效)



CAShapeLayer

使用CGPath绘制矢量图, UIBezierPath类可以创建基于矢量的路径,此类是Core Graphics框架关于path的一个封装。它可以定义简单的形状,如椭圆或者矩形,或者有多个直线和曲线段组成的形状。

源码在这里下载:http://www.informit.com/title/9780133440751


例子6.1
[objc]  view plain copy print ?
  1. @interface ViewController ()  
  2.   
  3. @property (nonatomic, weak) IBOutlet UIView *containerView;  
  4.   
  5. @end  
  6.   
  7. @implementation ViewController  
  8.   
  9. - (void)viewDidLoad  
  10. {  
  11.     [super viewDidLoad];  
  12.       
  13.     //create path  
  14.     UIBezierPath *path = [[UIBezierPath alloc] init];  
  15.     [path moveToPoint:CGPointMake(175100)];  
  16.     [path addArcWithCenter:CGPointMake(150100) radius:25 startAngle:0 endAngle:2*M_PI clockwise:YES];  
  17.     [path moveToPoint:CGPointMake(150125)];  
  18.     [path addLineToPoint:CGPointMake(150175)];  
  19.     [path addLineToPoint:CGPointMake(125225)];  
  20.     [path moveToPoint:CGPointMake(150175)];  
  21.     [path addLineToPoint:CGPointMake(175225)];  
  22.     [path moveToPoint:CGPointMake(100150)];  
  23.     [path addLineToPoint:CGPointMake(200150)];  
  24.       
  25.     //create shape layer  
  26.     CAShapeLayer *shapeLayer = [CAShapeLayer layer];  
  27.     shapeLayer.strokeColor = [UIColor redColor].CGColor;  
  28.     shapeLayer.fillColor = [UIColor clearColor].CGColor;  
  29.     shapeLayer.lineWidth = 5;  
  30.     shapeLayer.lineJoin = kCALineJoinRound;  
  31.     shapeLayer.lineCap = kCALineCapRound;  
  32.     shapeLayer.path = path.CGPath;  
  33.       
  34.     //add it to our view  
  35.     [self.containerView.layer addSublayer:shapeLayer];  
  36. }  
  37.   
  38. @end  
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第41张图片


先说说CAShapeLayer的属性设置

1. 线颜色
[objc]  view plain copy print ?
  1. @property CGColorRef strokeColor  

2. 填充色
[objc]  view plain copy print ?
  1. @property CGColorRef fillColor  

3. 填充规则
[objc]  view plain copy print ?
  1. @property(copyNSString *fillRule  
修改例子6.1
默认值kCAFillRuleNonZero的情况
[objc]  view plain copy print ?
  1. - (void)viewDidLoad  
  2. {  
  3.     [super viewDidLoad];  
  4.       
  5.     //create path  
  6.     UIBezierPath *path = [[UIBezierPath alloc] init];  
  7.     [path moveToPoint:CGPointMake(200150)];  
  8.     [path addArcWithCenter:CGPointMake(150150) radius:50 startAngle:0 endAngle:2*M_PI clockwise:YES];  
  9.     [path moveToPoint:CGPointMake(250150)];  
  10.     [path addArcWithCenter:CGPointMake(150150) radius:100 startAngle:0 endAngle:2*M_PI clockwise:YES];  
  11.   
  12.     //create shape layer  
  13.     CAShapeLayer *shapeLayer = [CAShapeLayer layer];  
  14.     shapeLayer.strokeColor = [UIColor redColor].CGColor;  
  15.     shapeLayer.fillColor = [UIColor blueColor].CGColor;  
  16.     shapeLayer.fillRule = kCAFillRuleNonZero;  
  17.     //shapeLayer.fillRule = kCAFillRuleEvenOdd;  
  18.   
  19.     shapeLayer.lineWidth = 5;  
  20.     shapeLayer.lineJoin = kCALineJoinBevel;  
  21.     shapeLayer.lineCap = kCALineCapRound;  
  22.     shapeLayer.path = path.CGPath;  
  23.       
  24.     //add it to our view  
  25.     [self.containerView.layer addSublayer:shapeLayer];  
  26. }  
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第42张图片
再修改
[objc]  view plain copy print ?
  1. - (void)viewDidLoad  
  2. {  
  3.     [super viewDidLoad];  
  4.       
  5.     //create path  
  6.     UIBezierPath *path = [[UIBezierPath alloc] init];  
  7.     [path moveToPoint:CGPointMake(200150)];  
  8.     [path addArcWithCenter:CGPointMake(150150) radius:50 startAngle:0 endAngle:2*M_PI clockwise:YES];  
  9.     [path moveToPoint:CGPointMake(250150)];  
  10.     [path addArcWithCenter:CGPointMake(150150) radius:100 startAngle:0 endAngle:-2*M_PI clockwise:NO];  
  11.   
  12.     //create shape layer  
  13.     CAShapeLayer *shapeLayer = [CAShapeLayer layer];  
  14.     shapeLayer.strokeColor = [UIColor redColor].CGColor;  
  15.     shapeLayer.fillColor = [UIColor blueColor].CGColor;  
  16.     shapeLayer.fillRule = kCAFillRuleNonZero;  
  17.     //shapeLayer.fillRule = kCAFillRuleEvenOdd;  
  18.   
  19.     shapeLayer.lineWidth = 5;  
  20.     shapeLayer.lineJoin = kCALineJoinBevel;  
  21.     shapeLayer.lineCap = kCALineCapRound;  
  22.     shapeLayer.path = path.CGPath;  
  23.       
  24.     //add it to our view  
  25.     [self.containerView.layer addSublayer:shapeLayer];  
  26. }  
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第43张图片

kCAFillRuleEvenOdd的情况

修改代码
[objc]  view plain copy print ?
  1. - (void)viewDidLoad  
  2. {  
  3.     [super viewDidLoad];  
  4.       
  5.     //create path  
  6.     UIBezierPath *path = [[UIBezierPath alloc] init];  
  7.     [path moveToPoint:CGPointMake(200150)];  
  8.     [path addArcWithCenter:CGPointMake(150150) radius:50 startAngle:0 endAngle:2*M_PI clockwise:YES];  
  9.     [path moveToPoint:CGPointMake(250150)];  
  10.     [path addArcWithCenter:CGPointMake(150150) radius:100 startAngle:0 endAngle:2*M_PI clockwise:YES];  
  11.   
  12.     //create shape layer  
  13.     CAShapeLayer *shapeLayer = [CAShapeLayer layer];  
  14.     shapeLayer.strokeColor = [UIColor redColor].CGColor;  
  15.     shapeLayer.fillColor = [UIColor blueColor].CGColor;  
  16.     //shapeLayer.fillRule = kCAFillRuleNonZero;  
  17.     shapeLayer.fillRule = kCAFillRuleEvenOdd;  
  18.   
  19.     shapeLayer.lineWidth = 5;  
  20.     shapeLayer.lineJoin = kCALineJoinBevel;  
  21.     shapeLayer.lineCap = kCALineCapRound;  
  22.     shapeLayer.path = path.CGPath;  
  23.       
  24.     //add it to our view  
  25.     [self.containerView.layer addSublayer:shapeLayer];  
  26. }  
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第44张图片

同样修改
[objc]  view plain copy print ?
  1. - (void)viewDidLoad  
  2. {  
  3.     [super viewDidLoad];  
  4.       
  5.     //create path  
  6.     UIBezierPath *path = [[UIBezierPath alloc] init];  
  7.     [path moveToPoint:CGPointMake(200150)];  
  8.     [path addArcWithCenter:CGPointMake(150150) radius:50 startAngle:0 endAngle:2*M_PI clockwise:YES];  
  9.     [path moveToPoint:CGPointMake(250150)];  
  10.     [path addArcWithCenter:CGPointMake(150150) radius:100 startAngle:0 endAngle:-2*M_PI clockwise:NO];  
  11.   
  12.     //create shape layer  
  13.     CAShapeLayer *shapeLayer = [CAShapeLayer layer];  
  14.     shapeLayer.strokeColor = [UIColor redColor].CGColor;  
  15.     shapeLayer.fillColor = [UIColor blueColor].CGColor;  
  16.     //shapeLayer.fillRule = kCAFillRuleNonZero;  
  17.     shapeLayer.fillRule = kCAFillRuleEvenOdd;  
  18.   
  19.     shapeLayer.lineWidth = 5;  
  20.     shapeLayer.lineJoin = kCALineJoinBevel;  
  21.     shapeLayer.lineCap = kCALineCapRound;  
  22.     shapeLayer.path = path.CGPath;  
  23.       
  24.     //add it to our view  
  25.     [self.containerView.layer addSublayer:shapeLayer];  
  26. }  
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第45张图片
继续为了看清奇偶的效果,画3个同方向圆圈
[objc]  view plain copy print ?
  1. - (void)viewDidLoad  
  2. {  
  3.     [super viewDidLoad];  
  4.       
  5.     //create path  
  6.     UIBezierPath *path = [[UIBezierPath alloc] init];  
  7.     [path moveToPoint:CGPointMake(200150)];  
  8.     [path addArcWithCenter:CGPointMake(150150) radius:50 startAngle:0 endAngle:2*M_PI clockwise:YES];  
  9.     [path moveToPoint:CGPointMake(250150)];  
  10.     [path addArcWithCenter:CGPointMake(150150) radius:100 startAngle:0 endAngle:2*M_PI clockwise:YES];  
  11.     [path moveToPoint:CGPointMake(300150)];  
  12.     [path addArcWithCenter:CGPointMake(150150) radius:150 startAngle:0 endAngle:2*M_PI clockwise:YES];  
  13.   
  14.     //create shape layer  
  15.     CAShapeLayer *shapeLayer = [CAShapeLayer layer];  
  16.     shapeLayer.strokeColor = [UIColor redColor].CGColor;  
  17.     shapeLayer.fillColor = [UIColor blueColor].CGColor;  
  18.     //shapeLayer.fillRule = kCAFillRuleNonZero;  
  19.     shapeLayer.fillRule = kCAFillRuleEvenOdd;  
  20.   
  21.     shapeLayer.lineWidth = 5;  
  22.     shapeLayer.lineJoin = kCALineJoinBevel;  
  23.     shapeLayer.lineCap = kCALineCapRound;  
  24.     shapeLayer.path = path.CGPath;  
  25.       
  26.     //add it to our view  
  27.     [self.containerView.layer addSublayer:shapeLayer];  
  28. }  
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第46张图片

以上我们应该清楚不同的规则了吧,挪用别人的描述

nonzero字面意思是“非零”。按该规则,要判断一个点是否在图形内,从该点作任意方向的一条射线,然后检测射线与图形路径的交点情况。从0开始计数,路径从左向右穿过射线则计数加1,从右向左穿过射线则计数减1。得出计数结果后,如果结果是0,则认为点在图形外部,否则认为在内部。下图演示了nonzero规则:

IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第47张图片


evenodd字面意思是“奇偶”。按该规则,要判断一个点是否在图形内,从该点作任意方向的一条射线,然后检测射线与图形路径的交点的数量。如果结果是奇数则认为点在内部,是偶数则认为点在外部。下图演示了 evenodd 规则: IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第48张图片

4. 线端点类型
[objc]  view plain copy print ?
  1. @property(copyNSString *lineCap  
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第49张图片

5. 线连接类型
[objc]  view plain copy print ?
  1. @property(copyNSString *lineJoin  
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第50张图片

6. 线宽
[objc]  view plain copy print ?
  1. @property CGFloat lineWidth  

7. 线型模板
[objc]  view plain copy print ?
  1. @property(copyNSArray *lineDashPattern  
这是一个NSNumber的数组,索引从1开始记,奇数位数值表示实线长度,偶数位数值表示空白长度

8. 线型模板的起始位置
[objc]  view plain copy print ?
  1. @property CGFloat lineDashPhase  
修改例子6.1,为了看得更清楚,把lineCap的设置注释,,自己看看不注释是什么结果
[objc]  view plain copy print ?
  1. - (void)viewDidLoad  
  2. {  
  3.     [super viewDidLoad];  
  4.   
  5.     //create path  
  6.     UIBezierPath *path = [[UIBezierPath alloc] init];  
  7.     [path moveToPoint:CGPointMake(175100)];  
  8.     [path addArcWithCenter:CGPointMake(150100) radius:25 startAngle:0 endAngle:2*M_PI clockwise:YES];  
  9.     [path moveToPoint:CGPointMake(150125)];  
  10.     [path addLineToPoint:CGPointMake(150175)];  
  11.     [path addLineToPoint:CGPointMake(125225)];  
  12.     [path moveToPoint:CGPointMake(150175)];  
  13.     [path addLineToPoint:CGPointMake(175225)];  
  14.     [path moveToPoint:CGPointMake(100150)];  
  15.     [path addLineToPoint:CGPointMake(200150)];  
  16.   
  17.     //create shape layer  
  18.     CAShapeLayer *shapeLayer = [CAShapeLayer layer];  
  19.     shapeLayer.strokeColor = [UIColor redColor].CGColor;  
  20.     shapeLayer.fillColor = [UIColor clearColor].CGColor;  
  21.   
  22.     shapeLayer.lineWidth = 5;  
  23.     shapeLayer.lineDashPattern = [NSArray arrayWithObjects:[NSNumber numberWithInt:20], [NSNumber numberWithInt:10], [NSNumber numberWithInt:10], [NSNumber numberWithInt:2], nil nil];  
  24.     //shapeLayer.lineDashPhase = 15;  
  25.     shapeLayer.lineJoin = kCALineJoinBevel;  
  26.     //shapeLayer.lineCap = kCALineCapRound;  
  27. //    shapeLayer.strokeStart = 0.1;  
  28. //    shapeLayer.strokeEnd = 0.6;  
  29.     shapeLayer.path = path.CGPath;  
  30.   
  31.     //add it to our view  
  32.     [self.containerView.layer addSublayer:shapeLayer];  
  33. }  
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第51张图片
再修改lineDashPhase值=15
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第52张图片



9. 最大斜接长度。

[objc]  view plain copy print ?
  1. @property CGFloat miterLimit  

斜接长度指的是在两条线交汇处内角和外角之间的距离。

IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第53张图片

只有lineJoin属性为kCALineJoinMiter时miterLimit才有效

边角的角度越小,斜接长度就会越大。

为了避免斜接长度过长,我们可以使用 miterLimit 属性。

如果斜接长度超过 miterLimit 的值,边角会以 lineJoin "bevel"即kCALineJoinBevel类型来显示

IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第54张图片


10. 部分绘线
[objc]  view plain copy print ?
  1. @property CGFloat strokeStart  
  2. @property CGFloat strokeEnd  

都是0.0~1.0的取值范围
具体看修改例子6.1
[objc]  view plain copy print ?
  1. - (void)viewDidLoad  
  2. {  
  3.     [super viewDidLoad];  
  4.   
  5.     //create path  
  6.     UIBezierPath *path = [[UIBezierPath alloc] init];  
  7.     [path moveToPoint:CGPointMake(175100)];  
  8.     [path addArcWithCenter:CGPointMake(150100) radius:25 startAngle:0 endAngle:2*M_PI clockwise:YES];  
  9.     [path moveToPoint:CGPointMake(150125)];  
  10.     [path addLineToPoint:CGPointMake(150175)];  
  11.     [path addLineToPoint:CGPointMake(125225)];  
  12.     [path moveToPoint:CGPointMake(150175)];  
  13.     [path addLineToPoint:CGPointMake(175225)];  
  14.     [path moveToPoint:CGPointMake(100150)];  
  15.     [path addLineToPoint:CGPointMake(200150)];  
  16.   
  17.     //create shape layer  
  18.     CAShapeLayer *shapeLayer = [CAShapeLayer layer];  
  19.     shapeLayer.strokeColor = [UIColor redColor].CGColor;  
  20.     shapeLayer.fillColor = [UIColor clearColor].CGColor;  
  21.   
  22.     shapeLayer.lineWidth = 5;  
  23.     //shapeLayer.lineDashPattern = [NSArray arrayWithObjects:[NSNumber numberWithInt:20], [NSNumber numberWithInt:10], [NSNumber numberWithInt:10], [NSNumber numberWithInt:2], nil];  
  24.     //shapeLayer.lineDashPhase = 15;  
  25.     shapeLayer.lineJoin = kCALineJoinBevel;  
  26.     shapeLayer.lineCap = kCALineCapRound;  
  27.     shapeLayer.strokeStart = 0.1;  
  28.     shapeLayer.strokeEnd = 0.6;  
  29.     shapeLayer.path = path.CGPath;  
  30.   
  31.     //add it to our view  
  32.     [self.containerView.layer addSublayer:shapeLayer];  
  33. }  
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第55张图片



UIBezierPath贝塞尔曲线的常用绘图方法

1. 矩形
[objc]  view plain copy print ?
  1. + (UIBezierPath *)bezierPathWithRect:(CGRect)rect  

2. 矩形内切椭圆
[objc]  view plain copy print ?
  1. + (UIBezierPath *)bezierPathWithOvalInRect:(CGRect)rect  

3. 圆角矩形
[objc]  view plain copy print ?
  1. + (UIBezierPath *)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius  

4. 可设置的圆角矩形
[objc]  view plain copy print ?
  1. + (UIBezierPath *)bezierPathWithRoundedRect:(CGRect)rect byRoundingCorners:(UIRectCorner)corners cornerRadii:(CGSize)cornerRadii  

corners有以下几种类型:

   UIRectCornerTopLeft,

   UIRectCornerTopRight,

   UIRectCornerBottomLeft,

   UIRectCornerBottomRight,

   UIRectCornerAllCorners


cornerRadii表示的是四个圆角拼成的椭圆的长、短半径尺寸。


5. 圆弧
[objc]  view plain copy print ?
  1. + (UIBezierPath *)bezierPathWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise  
  2. - (void)addArcWithCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise  

IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第56张图片 IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第57张图片


以下需要配合moveToPoint使用
[objc]  view plain copy print ?
  1. - (void)moveToPoint:(CGPoint)point  

6. 直线
[objc]  view plain copy print ?
  1. - (void)addLineToPoint:(CGPoint)point  

7. 曲线
[objc]  view plain copy print ?
  1. - (void)addCurveToPoint:(CGPoint)endPoint controlPoint1:(CGPoint)controlPoint1 controlPoint2:(CGPoint)controlPoint2  
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第58张图片

8. 二元曲线
[objc]  view plain copy print ?
  1. - (void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint  
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第59张图片

UIBezierPath的属性设置(这些属性在使用 CAShapeLayer时,只遵循CAShapeLayer的设置)
1. 线宽
[objc]  view plain copy print ?
  1. @property(nonatomic) CGFloat lineWidth  


2. 端点类型
[objc]  view plain copy print ?
  1. @property(nonatomic) CGLineCap lineCapStyle  


3. 连接类型
[objc]  view plain copy print ?
  1. @property(nonatomic) CGLineJoin lineJoinStyle  


4. 设置线型
[objc]  view plain copy print ?
  1. - (void)setLineDash:(const CGFloat *)pattern count:(NSInteger)count phase:(CGFloat)phase  

pattern:C类型的线型数据。如:CGFloat dashStyle[] = { 1.0f, 2.0f };

count:pattern中的数据个数
phase: 开始画线型的起始位置


其他的我在这里就不多说了


CATextLayer

例子6.2
[objc]  view plain copy print ?
  1. @interface ViewController ()  
  2.   
  3. @property (nonatomic, weak) IBOutlet UIView *labelView;  
  4.   
  5. @end  
  6.   
  7. @implementation ViewController  
  8.   
  9. - (void)viewDidLoad  
  10. {  
  11.     [super viewDidLoad];  
  12.       
  13.     //create a text layer  
  14.     CATextLayer *textLayer = [CATextLayer layer];  
  15.     textLayer.frame = self.labelView.bounds;  
  16.     [self.labelView.layer addSublayer:textLayer];  
  17.   
  18.     //uncomment the line below to fix pixelation on Retina screens  
  19.     //textLayer.contentsScale = [UIScreen mainScreen].scale;  
  20.       
  21.     //set text attributes  
  22.     textLayer.foregroundColor = [UIColor blackColor].CGColor;  
  23.     textLayer.alignmentMode = kCAAlignmentJustified;  
  24.     //textLayer.contentsScale = 1;  
  25.     textLayer.wrapped = YES;  
  26.       
  27.     //choose a font  
  28.     UIFont *font = [UIFont systemFontOfSize:15];  
  29.       
  30.     //set layer font  
  31.     CFStringRef fontName = (__bridge CFStringRef)font.fontName;  
  32.     CGFontRef fontRef = CGFontCreateWithFontName(fontName);  
  33.     textLayer.font = fontRef;  
  34.     textLayer.fontSize = font.pointSize;  
  35.     CGFontRelease(fontRef);  
  36.       
  37.     //choose some text  
  38.     NSString *text = @"Lorem ipsum dolor sit amet, consectetur adipiscing \ 
  39.     elit. Quisque massa arcu, eleifend vel varius in, facilisis pulvinar \ 
  40.     leo. Nunc quis nunc at mauris pharetra condimentum ut ac neque. Nunc \ 
  41.     elementum, libero ut porttitor dictum, diam odio congue lacus, vel \ 
  42.     fringilla sapien diam at purus. Etiam suscipit pretium nunc sit amet \ 
  43.     lobortis";  
  44.       
  45.     //set layer text  
  46.     textLayer.string = text;  
  47. }  
  48.   
  49. @end  
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第60张图片
仔细看文字周围很模糊,解决这个问题需要设置contentsScale
修改“textLayer.contentsScale = [UIScreen mainScreen].scale;”
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第61张图片


Rich Text

例子6.3
代码不贴了

CATextLayer also renders much faster than UILabel. It’s a little-known fact that on iOS6 and earlier,UILabel actually uses WebKit to do its text drawing, which carries a significant performance overhead when you are drawing a lot of text.CATextLayer uses Core Text and is significantlyfaster.


例子6.4使用layer实现的label,有兴趣的完善一下


CATransformLayer

例子6.5
代码不贴了

修改一下,可以实现简单的拖动旋转(只是试验代码)
[objc]  view plain copy print ?
  1. @interface ViewController ()  
  2. {  
  3.     CGPoint startPoint;  
  4.   
  5.     CATransformLayer *s_Cube;  
  6.   
  7.     float pix, piy;  
  8. }  
  9.   
  10. @property (nonatomic, weak) IBOutlet UIView *containerView;  
  11.   
  12. @end  
  13.   
  14. @implementation ViewController  
  15.   
  16. - (CALayer *)faceWithTransform:(CATransform3D)transform  
  17. {  
  18.     //create cube face layer  
  19.     CALayer *face = [CALayer layer];  
  20.     face.frame = CGRectMake(-50, -50100100);  
  21.       
  22.     //apply a random color  
  23.     CGFloat red = (rand() / (double)INT_MAX);  
  24.     CGFloat green = (rand() / (double)INT_MAX);  
  25.     CGFloat blue = (rand() / (double)INT_MAX);  
  26.     face.backgroundColor = [UIColor colorWithRed:red  
  27.                                            green:green  
  28.                                             blue:blue  
  29.                                            alpha:1.0].CGColor;  
  30.   
  31.     //apply the transform and return  
  32.     face.transform = transform;  
  33.     return face;  
  34. }  
  35.   
  36. - (CALayer *)cubeWithTransform:(CATransform3D)transform  
  37. {  
  38.     //create cube layer  
  39.     CATransformLayer *cube = [CATransformLayer layer];  
  40.       
  41.     //add cube face 1  
  42.     CATransform3D ct = CATransform3DMakeTranslation(0050);  
  43.     [cube addSublayer:[self faceWithTransform:ct]];  
  44.       
  45.     //add cube face 2  
  46.     ct = CATransform3DMakeTranslation(5000);  
  47.     ct = CATransform3DRotate(ct, M_PI_2010);  
  48.     [cube addSublayer:[self faceWithTransform:ct]];  
  49.       
  50.     //add cube face 3  
  51.     ct = CATransform3DMakeTranslation(0, -500);  
  52.     ct = CATransform3DRotate(ct, M_PI_2100);  
  53.     [cube addSublayer:[self faceWithTransform:ct]];  
  54.       
  55.     //add cube face 4  
  56.     ct = CATransform3DMakeTranslation(0500);  
  57.     ct = CATransform3DRotate(ct, -M_PI_2100);  
  58.     [cube addSublayer:[self faceWithTransform:ct]];  
  59.       
  60.     //add cube face 5  
  61.     ct = CATransform3DMakeTranslation(-5000);  
  62.     ct = CATransform3DRotate(ct, -M_PI_2010);  
  63.     [cube addSublayer:[self faceWithTransform:ct]];  
  64.       
  65.     //add cube face 6  
  66.     ct = CATransform3DMakeTranslation(00, -50);  
  67.     ct = CATransform3DRotate(ct, M_PI, 010);  
  68.     [cube addSublayer:[self faceWithTransform:ct]];  
  69.       
  70.     //center the cube layer within the container  
  71.     CGSize containerSize = self.containerView.bounds.size;  
  72.     cube.position = CGPointMake(containerSize.width / 2.0,  
  73.                                 containerSize.height / 2.0);  
  74.       
  75.     //apply the transform and return  
  76.     cube.transform = transform;  
  77.     return cube;  
  78. }  
  79.   
  80. - (void)viewDidLoad  
  81. {  
  82.     [super viewDidLoad];  
  83.       
  84.     //set up the perspective transform  
  85.     CATransform3D pt = CATransform3DIdentity;  
  86.     pt.m34 = -1.0 / 500.0;  
  87.     self.containerView.layer.sublayerTransform = pt;  
  88.       
  89.     //set up the transform for cube 1 and add it  
  90.     CATransform3D c1t = CATransform3DIdentity;  
  91.     c1t = CATransform3DTranslate(c1t, -10000);  
  92.     CALayer *cube1 = [self cubeWithTransform:c1t];  
  93.     s_Cube = (CATransformLayer *)cube1;  
  94.     [self.containerView.layer addSublayer:cube1];  
  95.       
  96.     //set up the transform for cube 2 and add it  
  97.     CATransform3D c2t = CATransform3DIdentity;  
  98.     c2t = CATransform3DTranslate(c2t, 10000);  
  99.     c2t = CATransform3DRotate(c2t, -M_PI_4100);  
  100.     c2t = CATransform3DRotate(c2t, -M_PI_4010);  
  101.     CALayer *cube2 = [self cubeWithTransform:c2t];  
  102.     [self.containerView.layer addSublayer:cube2];  
  103. }  
  104.   
  105. - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event  
  106. {  
  107.     UITouch *touch = [touches anyObject];  
  108.   
  109.     startPoint = [touch locationInView:self.view];  
  110. }  
  111.   
  112. - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event  
  113. {  
  114.     UITouch *touch = [touches anyObject];  
  115.   
  116.     CGPoint currentPosition = [touch locationInView:self.view];  
  117.   
  118.     CGFloat deltaX = startPoint.x - currentPosition.x;  
  119.   
  120.     CGFloat deltaY = startPoint.y - currentPosition.y;  
  121.   
  122.     CATransform3D c1t = CATransform3DIdentity;  
  123.     c1t = CATransform3DTranslate(c1t, -10000);  
  124.     c1t = CATransform3DRotate(c1t, pix+M_PI_2*deltaY/100100);  
  125.     c1t = CATransform3DRotate(c1t, piy-M_PI_2*deltaX/100010);  
  126.   
  127.     s_Cube.transform = c1t;  
  128. }  
  129.   
  130. - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event  
  131. {  
  132.     UITouch *touch = [touches anyObject];  
  133.   
  134.     CGPoint currentPosition = [touch locationInView:self.view];  
  135.   
  136.     CGFloat deltaX = startPoint.x - currentPosition.x;  
  137.   
  138.     CGFloat deltaY = startPoint.y - currentPosition.y;  
  139.   
  140.     pix = M_PI_2*deltaY/100;  
  141.     piy = -M_PI_2*deltaX/100;  
  142. }  
  143.   
  144. @end  
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第62张图片


CAGradientLayer

产生平滑过渡色,
例子6.6
[objc]  view plain copy print ?
  1. interface ViewController ()  
  2.   
  3. @property (nonatomic, weak) IBOutlet UIView *containerView;  
  4.   
  5. @end  
  6.   
  7. @implementation ViewController  
  8.   
  9. - (void)viewDidLoad  
  10. {  
  11.     [super viewDidLoad];  
  12.       
  13.     //create gradient layer and add it to our container view  
  14.     CAGradientLayer *gradientLayer = [CAGradientLayer layer];  
  15.     gradientLayer.frame = self.containerView.bounds;  
  16.     [self.containerView.layer addSublayer:gradientLayer];  
  17.       
  18.     //set gradient colors  
  19.     gradientLayer.colors = @[(__bridge id)[UIColor redColor].CGColor,  
  20.                              (__bridge id)[UIColor blueColor].CGColor];  
  21.       
  22.     //set gradient start and end points  
  23.     gradientLayer.startPoint = CGPointMake(00);  
  24.     gradientLayer.endPoint = CGPointMake(11);      
  25. }  
  26.   
  27. @end  
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第63张图片

CAGradientLayer的属性设置

1. 类型
[objc]  view plain copy print ?
  1. @property(copyNSString *type  
目前只有NSString * const kCAGradientLayerAxial
即线性梯度变化

2. 颜色
[objc]  view plain copy print ?
  1. @property(copyNSArray *colors  
3. 位置参数
[objc]  view plain copy print ?
  1. @property(copyNSArray *locations  
颜色的区间分布,locations的数组长度和colors一致, 取值范围(0, 1),而且必须是单调递增的

修改例子6.6,增加
[objc]  view plain copy print ?
  1. <p class="p1">    gradientLayer.<span class="s1">locations</span> = <span class="s2">@[</span>[<span class="s1">NSNumber</span> <span class="s3">numberWithFloat</span>:<span class="s2">0.0</span>], [<span class="s1">NSNumber</span> <span class="s3">numberWithFloat</span>:<span class="s2">0.2</span>]<span class="s2">]</span>;</p>  
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第64张图片
[objc]  view plain copy print ?
  1. gradientLayer.locations = @[[NSNumber numberWithFloat:0.5], [NSNumber numberWithFloat:0.7]];  
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第65张图片

4. startPoint和endPoint
[objc]  view plain copy print ?
  1. @property CGPoint startPoint, endPoint;  
取值都是相对于layer的bounds的。startPoint默认值为(0.5, 0),endPoint默认值为(0.5, 1)

修改例子6.6

gradientLayer.startPoint 分别设为 CGPointMake(00); 

IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第66张图片

  CGPointMake( 0.250); 
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第67张图片

  CGPointMake( 0.50); 
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第68张图片

  CGPointMake( 0.750); 
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第69张图片

  CGPointMake(1,  0); 
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第70张图片


综合修改例子6.6
[objc]  view plain copy print ?
  1. - (void)viewDidLoad  
  2. {  
  3.     [super viewDidLoad];  
  4.       
  5.     //create gradient layer and add it to our container view  
  6.     CAGradientLayer *gradientLayer = [CAGradientLayer layer];  
  7.     gradientLayer.frame = self.containerView.bounds;  
  8.     [self.containerView.layer addSublayer:gradientLayer];  
  9.       
  10.     //set gradient colors  
  11.     gradientLayer.colors = @[(__bridge id)[UIColor redColor].CGColor,  
  12.                              (__bridge id)[UIColor blueColor].CGColor];  
  13.       
  14.     gradientLayer.locations = @[[NSNumber numberWithFloat:0.5], [NSNumber numberWithFloat:0.7]];  
  15.   
  16.     //set gradient start and end points  
  17.     gradientLayer.startPoint = CGPointMake(0.750.0);  
  18.     gradientLayer.endPoint = CGPointMake(1.01.0);  
  19. }  
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第71张图片


从以上可以看出startPoint和endPoint诗表示的渐变方向,locations是渐变区域。
也可以看出locations的取值是相对于startPoint和endPoint线段的。

在网上找的描述让我很是不能理解

IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第72张图片


CAReplicatorLayer

例子6.8,修改一下看得更清楚些
[objc]  view plain copy print ?
  1. @interface ViewController ()  
  2.   
  3. @property (nonatomic, weak) IBOutlet UIView *containerView;  
  4.   
  5. @end  
  6.   
  7. @implementation ViewController  
  8.   
  9. - (void)viewDidLoad  
  10. {  
  11.     [super viewDidLoad];  
  12.       
  13.     //create a replicator layer and add it to our view  
  14.     CAReplicatorLayer *replicator = [CAReplicatorLayer layer];  
  15.     replicator.frame = self.containerView.bounds;  
  16.     [self.containerView.layer addSublayer:replicator];  
  17.       
  18.     //configure the replicator  
  19.     replicator.instanceCount = 20;  
  20.       
  21.     //apply a transform for each instance  
  22.     CATransform3D transform = CATransform3DIdentity;  
  23.     transform = CATransform3DTranslate(transform, 0, -100);  
  24.     transform = CATransform3DRotate(transform, M_PI / 10.0001);  
  25.     transform = CATransform3DTranslate(transform, 0100);  
  26.     replicator.instanceTransform = transform;  
  27.       
  28.     //apply a color shift for each instance  
  29.     replicator.instanceBlueOffset = -0.1;  
  30.     replicator.instanceGreenOffset = -0.1;  
  31.       
  32.     //create a sublayer and place it inside the replicator  
  33.     CALayer *layer = [CALayer layer];  
  34.     layer.frame = CGRectMake(137.5f25.0f25.0f25.0f);  
  35.     layer.backgroundColor = [UIColor whiteColor].CGColor;  
  36.     [replicator addSublayer:layer];  
  37. }  
  38.   
  39. @end  
IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第73张图片

CAReplicatorLayer应用最多的可能是倒影了,下面的链接是个很好的图片倒影例子

https://github.com/nicklockwood/ReflectionView


后面的几个特殊layer我就不在这里列举了,自己去研究吧

下一次,就将进入真正的动画部分了




使用CAShapeLayer与UIBezierPath可以实现不在view的drawRect方法中就画出一些想要的图形

步骤:

1、新建UIBezierPath对象bezierPath

2、新建CAShapeLayer对象caShapeLayer

3、将bezierPath的CGPath赋值给caShapeLayer的path,即caShapeLayer.path = bezierPath.CGPath

4、把caShapeLayer添加到某个显示该图形的layer中


下面的小例子是一个环形的progress代码,有具体的使用方法

.h文件:

[cpp]  view plain copy
  1. #import <QuartzCore/QuartzCore.h>  
  2. #import <UIKit/UIKit.h>  
  3.   
  4. @interface KACircleProgressView : UIView {  
  5.     CAShapeLayer *_trackLayer;  
  6.     UIBezierPath *_trackPath;  
  7.     CAShapeLayer *_progressLayer;  
  8.     UIBezierPath *_progressPath;  
  9. }  
  10.   
  11. @property (nonatomic, strong) UIColor *trackColor;  
  12. @property (nonatomic, strong) UIColor *progressColor;  
  13. @property (nonatomic) float progress;//0~1之间的数  
  14. @property (nonatomic) float progressWidth;  
  15.   
  16. - (void)setProgress:(float)progress animated:(BOOL)animated;  
  17.   
  18. @end  


.m文件


[cpp]  view plain copy
  1. #import "KACircleProgressView.h"  
  2.   
  3. @implementation KACircleProgressView  
  4.   
  5. - (id)initWithFrame:(CGRect)frame  
  6. {  
  7.     self = [super initWithFrame:frame];  
  8.     if (self) {  
  9.         // Initialization code  
  10.         _trackLayer = [CAShapeLayer new];  
  11.         [self.layer addSublayer:_trackLayer];  
  12.         _trackLayer.fillColor = nil;  
  13.         _trackLayer.frame = self.bounds;  
  14.           
  15.         _progressLayer = [CAShapeLayer new];  
  16.         [self.layer addSublayer:_progressLayer];  
  17.         _progressLayer.fillColor = nil;  
  18.         _progressLayer.lineCap = kCALineCapRound;  
  19.         _progressLayer.frame = self.bounds;  
  20.           
  21.         //默认5  
  22.         self.progressWidth = 5;  
  23.     }  
  24.     return self;  
  25. }  
  26.   
  27. - (void)setTrack  
  28. {  
  29.     _trackPath = [UIBezierPath bezierPathWithArcCenter:self.center radius:(self.bounds.size.width - _progressWidth)/ 2 startAngle:0 endAngle:M_PI * 2 clockwise:YES];;  
  30.     _trackLayer.path = _trackPath.CGPath;  
  31. }  
  32.   
  33. - (void)setProgress  
  34. {  
  35.     _progressPath = [UIBezierPath bezierPathWithArcCenter:self.center radius:(self.bounds.size.width - _progressWidth)/ 2 startAngle:- M_PI_2 endAngle:(M_PI * 2) * _progress - M_PI_2 clockwise:YES];  
  36.     _progressLayer.path = _progressPath.CGPath;  
  37. }  
  38.   
  39.   
  40. - (void)setProgressWidth:(float)progressWidth  
  41. {  
  42.     _progressWidth = progressWidth;  
  43.     _trackLayer.lineWidth = _progressWidth;  
  44.     _progressLayer.lineWidth = _progressWidth;  
  45.       
  46.     [self setTrack];  
  47.     [self setProgress];  
  48. }  
  49.   
  50. - (void)setTrackColor:(UIColor *)trackColor  
  51. {  
  52.     _trackLayer.strokeColor = trackColor.CGColor;  
  53. }  
  54.   
  55. - (void)setProgressColor:(UIColor *)progressColor  
  56. {  
  57.     _progressLayer.strokeColor = progressColor.CGColor;  
  58. }  
  59.   
  60. - (void)setProgress:(float)progress  
  61. {  
  62.     _progress = progress;  
  63.       
  64.     [self setProgress];  
  65. }  
  66.   
  67. - (void)setProgress:(float)progress animated:(BOOL)animated  
  68. {  
  69.       
  70. }  
  71.   
  72. /* 
  73. // Only override drawRect: if you perform custom drawing. 
  74. // An empty implementation adversely affects performance during animation. 
  75. - (void)drawRect:(CGRect)rect 
  76. { 
  77.     // Drawing code 
  78. } 
  79. */  
  80.   
  81. @end  


使用:

[cpp]  view plain copy
  1. - (void)viewDidLoad  
  2. {  
  3.     [super viewDidLoad];  
  4.     // Do any additional setup after loading the view, typically from a nib.  
  5.     KACircleProgressView *progress = [[KACircleProgressView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];  
  6.     [self.view addSubview:progress];  
  7.     progress.trackColor = [UIColor blackColor];  
  8.     progress.progressColor = [UIColor orangeColor];  
  9.     progress.progress = .7;  
  10.     progress.progressWidth = 10;  
  11. }  


最后上一张效果图:


IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形_第74张图片


 

IOS Core Animation Advanced Techniques的学习笔记(1-5)

http://blog.csdn.net/iunion/article/details/25420849

出在:http://blog.csdn.net/iunion/article/details/26221213


你可能感兴趣的:(IOS Core Animation Advanced Techniques-使用CAShapeLayer与UIBezierPath画出想要的图形)