IOS Core Animation Advanced Techniques的学习笔记(五)

第六章: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

  1. @interface ViewController ()
  2. @property (nonatomic, weak) IBOutlet UIView *containerView;
  3. @end
  4. @implementation ViewController
  5. - (void)viewDidLoad
  6. {
  7. [super viewDidLoad];
  8. //create path
  9. UIBezierPath *path = [[UIBezierPath alloc] init];
  10. [path moveToPoint:CGPointMake(175, 100)];
  11. [path addArcWithCenter:CGPointMake(150, 100) radius:25 startAngle:0 endAngle:2*M_PI clockwise:YES];
  12. [path moveToPoint:CGPointMake(150, 125)];
  13. [path addLineToPoint:CGPointMake(150, 175)];
  14. [path addLineToPoint:CGPointMake(125, 225)];
  15. [path moveToPoint:CGPointMake(150, 175)];
  16. [path addLineToPoint:CGPointMake(175, 225)];
  17. [path moveToPoint:CGPointMake(100, 150)];
  18. [path addLineToPoint:CGPointMake(200, 150)];
  19. //create shape layer
  20. CAShapeLayer *shapeLayer = [CAShapeLayer layer];
  21. shapeLayer.strokeColor = [UIColor redColor].CGColor;
  22. shapeLayer.fillColor = [UIColor clearColor].CGColor;
  23. shapeLayer.lineWidth = 5;
  24. shapeLayer.lineJoin = kCALineJoinRound;
  25. shapeLayer.lineCap = kCALineCapRound;
  26. shapeLayer.path = path.CGPath;
  27. //add it to our view
  28. [self.containerView.layer addSublayer:shapeLayer];
  29. }
  30. @end

IOS Core Animation Advanced Techniques的学习笔记(五)

 
 
先说说CAShapeLayer的属性设置
 
1. 线颜色
  1. @property CGColorRef strokeColor
 
2. 填充色
  1. @property CGColorRef fillColor

3. 填充规则

  1. @property(copy) NSString *fillRule

修改例子6.1

默认值kCAFillRuleNonZero的情况
  1. - (void)viewDidLoad
  2. {
  3. [super viewDidLoad];
  4. //create path
  5. UIBezierPath *path = [[UIBezierPath alloc] init];
  6. [path moveToPoint:CGPointMake(200, 150)];
  7. [path addArcWithCenter:CGPointMake(150, 150) radius:50 startAngle:0 endAngle:2*M_PI clockwise:YES];
  8. [path moveToPoint:CGPointMake(250, 150)];
  9. [path addArcWithCenter:CGPointMake(150, 150) radius:100 startAngle:0 endAngle:2*M_PI clockwise:YES];
  10. //create shape layer
  11. CAShapeLayer *shapeLayer = [CAShapeLayer layer];
  12. shapeLayer.strokeColor = [UIColor redColor].CGColor;
  13. shapeLayer.fillColor = [UIColor blueColor].CGColor;
  14. shapeLayer.fillRule = kCAFillRuleNonZero;
  15. //shapeLayer.fillRule = kCAFillRuleEvenOdd;
  16. shapeLayer.lineWidth = 5;
  17. shapeLayer.lineJoin = kCALineJoinBevel;
  18. shapeLayer.lineCap = kCALineCapRound;
  19. shapeLayer.path = path.CGPath;
  20. //add it to our view
  21. [self.containerView.layer addSublayer:shapeLayer];
  22. }

IOS Core Animation Advanced Techniques的学习笔记(五)
再修改

  1. - (void)viewDidLoad
  2. {
  3. [super viewDidLoad];
  4. //create path
  5. UIBezierPath *path = [[UIBezierPath alloc] init];
  6. [path moveToPoint:CGPointMake(200, 150)];
  7. [path addArcWithCenter:CGPointMake(150, 150) radius:50 startAngle:0 endAngle:2*M_PI clockwise:YES];
  8. [path moveToPoint:CGPointMake(250, 150)];
  9. [path addArcWithCenter:CGPointMake(150, 150) radius:100 startAngle:0 endAngle:-2*M_PI clockwise:NO];
  10. //create shape layer
  11. CAShapeLayer *shapeLayer = [CAShapeLayer layer];
  12. shapeLayer.strokeColor = [UIColor redColor].CGColor;
  13. shapeLayer.fillColor = [UIColor blueColor].CGColor;
  14. shapeLayer.fillRule = kCAFillRuleNonZero;
  15. //shapeLayer.fillRule = kCAFillRuleEvenOdd;
  16. shapeLayer.lineWidth = 5;
  17. shapeLayer.lineJoin = kCALineJoinBevel;
  18. shapeLayer.lineCap = kCALineCapRound;
  19. shapeLayer.path = path.CGPath;
  20. //add it to our view
  21. [self.containerView.layer addSublayer:shapeLayer];
  22. }

IOS Core Animation Advanced Techniques的学习笔记(五)

 

kCAFillRuleEvenOdd的情况

修改代码

  1. - (void)viewDidLoad
  2. {
  3. [super viewDidLoad];
  4. //create path
  5. UIBezierPath *path = [[UIBezierPath alloc] init];
  6. [path moveToPoint:CGPointMake(200, 150)];
  7. [path addArcWithCenter:CGPointMake(150, 150) radius:50 startAngle:0 endAngle:2*M_PI clockwise:YES];
  8. [path moveToPoint:CGPointMake(250, 150)];
  9. [path addArcWithCenter:CGPointMake(150, 150) radius:100 startAngle:0 endAngle:2*M_PI clockwise:YES];
  10. //create shape layer
  11. CAShapeLayer *shapeLayer = [CAShapeLayer layer];
  12. shapeLayer.strokeColor = [UIColor redColor].CGColor;
  13. shapeLayer.fillColor = [UIColor blueColor].CGColor;
  14. //shapeLayer.fillRule = kCAFillRuleNonZero;
  15. shapeLayer.fillRule = kCAFillRuleEvenOdd;
  16. shapeLayer.lineWidth = 5;
  17. shapeLayer.lineJoin = kCALineJoinBevel;
  18. shapeLayer.lineCap = kCALineCapRound;
  19. shapeLayer.path = path.CGPath;
  20. //add it to our view
  21. [self.containerView.layer addSublayer:shapeLayer];
  22. }

IOS Core Animation Advanced Techniques的学习笔记(五)

 
同样修改
  1. - (void)viewDidLoad
  2. {
  3. [super viewDidLoad];
  4. //create path
  5. UIBezierPath *path = [[UIBezierPath alloc] init];
  6. [path moveToPoint:CGPointMake(200, 150)];
  7. [path addArcWithCenter:CGPointMake(150, 150) radius:50 startAngle:0 endAngle:2*M_PI clockwise:YES];
  8. [path moveToPoint:CGPointMake(250, 150)];
  9. [path addArcWithCenter:CGPointMake(150, 150) radius:100 startAngle:0 endAngle:-2*M_PI clockwise:NO];
  10. //create shape layer
  11. CAShapeLayer *shapeLayer = [CAShapeLayer layer];
  12. shapeLayer.strokeColor = [UIColor redColor].CGColor;
  13. shapeLayer.fillColor = [UIColor blueColor].CGColor;
  14. //shapeLayer.fillRule = kCAFillRuleNonZero;
  15. shapeLayer.fillRule = kCAFillRuleEvenOdd;
  16. shapeLayer.lineWidth = 5;
  17. shapeLayer.lineJoin = kCALineJoinBevel;
  18. shapeLayer.lineCap = kCALineCapRound;
  19. shapeLayer.path = path.CGPath;
  20. //add it to our view
  21. [self.containerView.layer addSublayer:shapeLayer];
  22. }

IOS Core Animation Advanced Techniques的学习笔记(五)
继续为了看清奇偶的效果,画3个同方向圆圈

 
  1. - (void)viewDidLoad
  2. {
  3. [super viewDidLoad];
  4. //create path
  5. UIBezierPath *path = [[UIBezierPath alloc] init];
  6. [path moveToPoint:CGPointMake(200, 150)];
  7. [path addArcWithCenter:CGPointMake(150, 150) radius:50 startAngle:0 endAngle:2*M_PI clockwise:YES];
  8. [path moveToPoint:CGPointMake(250, 150)];
  9. [path addArcWithCenter:CGPointMake(150, 150) radius:100 startAngle:0 endAngle:2*M_PI clockwise:YES];
  10. [path moveToPoint:CGPointMake(300, 150)];
  11. [path addArcWithCenter:CGPointMake(150, 150) radius:150 startAngle:0 endAngle:2*M_PI clockwise:YES];
  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. shapeLayer.lineWidth = 5;
  19. shapeLayer.lineJoin = kCALineJoinBevel;
  20. shapeLayer.lineCap = kCALineCapRound;
  21. shapeLayer.path = path.CGPath;
  22. //add it to our view
  23. [self.containerView.layer addSublayer:shapeLayer];
  24. }

IOS Core Animation Advanced Techniques的学习笔记(五)

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

IOS Core Animation Advanced Techniques的学习笔记(五)

evenodd字面意思是“奇偶”。按该规则,要判断一个点是否在图形内,从该点作任意方向的一条射线,然后检测射线与图形路径的交点的数量。如果结果是奇数则认为点在内部,是偶数则认为点在外部。下图演示了evenodd 规则:IOS Core Animation Advanced Techniques的学习笔记(五)

 

4. 线端点类型

  1. @property(copy) NSString *lineCap

IOS Core Animation Advanced Techniques的学习笔记(五)

5. 线连接类型
  1. @property(copy) NSString *lineJoin

IOS Core Animation Advanced Techniques的学习笔记(五)

 
6. 线宽
  1. @property CGFloat lineWidth

7. 线型模板

  1. @property(copy) NSArray *lineDashPattern

这是一个NSNumber的数组,索引从1开始记,奇数位数值表示实线长度,偶数位数值表示空白长度

8. 线型模板的起始位置
  1. @property CGFloat lineDashPhase

修改例子6.1,为了看得更清楚,把lineCap的设置注释,,自己看看不注释是什么结果

  1. - (void)viewDidLoad
  2. {
  3. [super viewDidLoad];
  4. //create path
  5. UIBezierPath *path = [[UIBezierPath alloc] init];
  6. [path moveToPoint:CGPointMake(175, 100)];
  7. [path addArcWithCenter:CGPointMake(150, 100) radius:25 startAngle:0 endAngle:2*M_PI clockwise:YES];
  8. [path moveToPoint:CGPointMake(150, 125)];
  9. [path addLineToPoint:CGPointMake(150, 175)];
  10. [path addLineToPoint:CGPointMake(125, 225)];
  11. [path moveToPoint:CGPointMake(150, 175)];
  12. [path addLineToPoint:CGPointMake(175, 225)];
  13. [path moveToPoint:CGPointMake(100, 150)];
  14. [path addLineToPoint:CGPointMake(200, 150)];
  15. //create shape layer
  16. CAShapeLayer *shapeLayer = [CAShapeLayer layer];
  17. shapeLayer.strokeColor = [UIColor redColor].CGColor;
  18. shapeLayer.fillColor = [UIColor clearColor].CGColor;
  19. shapeLayer.lineWidth = 5;
  20. shapeLayer.lineDashPattern = [NSArray arrayWithObjects:[NSNumber numberWithInt:20], [NSNumber numberWithInt:10], [NSNumber numberWithInt:10], [NSNumber numberWithInt:2], nil nil];
  21. //shapeLayer.lineDashPhase = 15;
  22. shapeLayer.lineJoin = kCALineJoinBevel;
  23. //shapeLayer.lineCap = kCALineCapRound;
  24. //    shapeLayer.strokeStart = 0.1;
  25. //    shapeLayer.strokeEnd = 0.6;
  26. shapeLayer.path = path.CGPath;
  27. //add it to our view
  28. [self.containerView.layer addSublayer:shapeLayer];
  29. }

IOS Core Animation Advanced Techniques的学习笔记(五)
再修改lineDashPhase值=15
IOS Core Animation Advanced Techniques的学习笔记(五)

 

9. 最大斜接长度。

  1. @property CGFloat miterLimit

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

IOS Core Animation Advanced Techniques的学习笔记(五)

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

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

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

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

IOS Core Animation Advanced Techniques的学习笔记(五)

 
 
 
10. 部分绘线
  1. @property CGFloat strokeStart
  2. @property CGFloat strokeEnd

都是0.0~1.0的取值范围

具体看修改例子6.1
  1. - (void)viewDidLoad
  2. {
  3. [super viewDidLoad];
  4. //create path
  5. UIBezierPath *path = [[UIBezierPath alloc] init];
  6. [path moveToPoint:CGPointMake(175, 100)];
  7. [path addArcWithCenter:CGPointMake(150, 100) radius:25 startAngle:0 endAngle:2*M_PI clockwise:YES];
  8. [path moveToPoint:CGPointMake(150, 125)];
  9. [path addLineToPoint:CGPointMake(150, 175)];
  10. [path addLineToPoint:CGPointMake(125, 225)];
  11. [path moveToPoint:CGPointMake(150, 175)];
  12. [path addLineToPoint:CGPointMake(175, 225)];
  13. [path moveToPoint:CGPointMake(100, 150)];
  14. [path addLineToPoint:CGPointMake(200, 150)];
  15. //create shape layer
  16. CAShapeLayer *shapeLayer = [CAShapeLayer layer];
  17. shapeLayer.strokeColor = [UIColor redColor].CGColor;
  18. shapeLayer.fillColor = [UIColor clearColor].CGColor;
  19. shapeLayer.lineWidth = 5;
  20. //shapeLayer.lineDashPattern = [NSArray arrayWithObjects:[NSNumber numberWithInt:20], [NSNumber numberWithInt:10], [NSNumber numberWithInt:10], [NSNumber numberWithInt:2], nil];
  21. //shapeLayer.lineDashPhase = 15;
  22. shapeLayer.lineJoin = kCALineJoinBevel;
  23. shapeLayer.lineCap = kCALineCapRound;
  24. shapeLayer.strokeStart = 0.1;
  25. shapeLayer.strokeEnd = 0.6;
  26. shapeLayer.path = path.CGPath;
  27. //add it to our view
  28. [self.containerView.layer addSublayer:shapeLayer];
  29. }

IOS Core Animation Advanced Techniques的学习笔记(五)

 
 
UIBezierPath贝塞尔曲线的常用绘图方法
 
1. 矩形
  1. + (UIBezierPath *)bezierPathWithRect:(CGRect)rect

2. 矩形内切椭圆

  1. + (UIBezierPath *)bezierPathWithOvalInRect:(CGRect)rect

3. 圆角矩形

  1. + (UIBezierPath *)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius

4. 可设置的圆角矩形

  1. + (UIBezierPath *)bezierPathWithRoundedRect:(CGRect)rect byRoundingCorners:(UIRectCorner)corners cornerRadii:(CGSize)cornerRadii

corners有以下几种类型:

UIRectCornerTopLeft,

UIRectCornerTopRight,

UIRectCornerBottomLeft,

UIRectCornerBottomRight,

UIRectCornerAllCorners

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

 

5. 圆弧

  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的学习笔记(五)IOS Core Animation Advanced Techniques的学习笔记(五)
 
以下需要配合moveToPoint使用
  1. - (void)moveToPoint:(CGPoint)point
 
6. 直线
  1. - (void)addLineToPoint:(CGPoint)point
7. 曲线
  1. - (void)addCurveToPoint:(CGPoint)endPoint controlPoint1:(CGPoint)controlPoint1 controlPoint2:(CGPoint)controlPoint2
IOS Core Animation Advanced Techniques的学习笔记(五)
 

8. 二元曲线

  1. - (void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint

IOS Core Animation Advanced Techniques的学习笔记(五)

UIBezierPath的属性设置(这些属性在使用CAShapeLayer时,只遵循CAShapeLayer的设置)
1. 线宽
  1. @property(nonatomic) CGFloat lineWidth

2. 端点类型

  1. @property(nonatomic) CGLineCap lineCapStyle
 
3. 连接类型
  1. @property(nonatomic) CGLineJoin lineJoinStyle
 
 
4. 设置线型
  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
  1. @interface ViewController ()
  2. @property (nonatomic, weak) IBOutlet UIView *labelView;
  3. @end
  4. @implementation ViewController
  5. - (void)viewDidLoad
  6. {
  7. [super viewDidLoad];
  8. //create a text layer
  9. CATextLayer *textLayer = [CATextLayer layer];
  10. textLayer.frame = self.labelView.bounds;
  11. [self.labelView.layer addSublayer:textLayer];
  12. //uncomment the line below to fix pixelation on Retina screens
  13. //textLayer.contentsScale = [UIScreen mainScreen].scale;
  14. //set text attributes
  15. textLayer.foregroundColor = [UIColor blackColor].CGColor;
  16. textLayer.alignmentMode = kCAAlignmentJustified;
  17. //textLayer.contentsScale = 1;
  18. textLayer.wrapped = YES;
  19. //choose a font
  20. UIFont *font = [UIFont systemFontOfSize:15];
  21. //set layer font
  22. CFStringRef fontName = (__bridge CFStringRef)font.fontName;
  23. CGFontRef fontRef = CGFontCreateWithFontName(fontName);
  24. textLayer.font = fontRef;
  25. textLayer.fontSize = font.pointSize;
  26. CGFontRelease(fontRef);
  27. //choose some text
  28. NSString *text = @"Lorem ipsum dolor sit amet, consectetur adipiscing \
  29. elit. Quisque massa arcu, eleifend vel varius in, facilisis pulvinar \
  30. leo. Nunc quis nunc at mauris pharetra condimentum ut ac neque. Nunc \
  31. elementum, libero ut porttitor dictum, diam odio congue lacus, vel \
  32. fringilla sapien diam at purus. Etiam suscipit pretium nunc sit amet \
  33. lobortis";
  34. //set layer text
  35. textLayer.string = text;
  36. }
  37. @end

IOS Core Animation Advanced Techniques的学习笔记(五)
仔细看文字周围很模糊,解决这个问题需要设置contentsScale

 
修改“textLayer.contentsScale = [UIScreen mainScreen].scale;”
IOS Core Animation Advanced Techniques的学习笔记(五)
 
 
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
代码不贴了
 

修改一下,可以实现简单的拖动旋转(只是试验代码)

  1. @interface ViewController ()
  2. {
  3. CGPoint startPoint;
  4. CATransformLayer *s_Cube;
  5. float pix, piy;
  6. }
  7. @property (nonatomic, weak) IBOutlet UIView *containerView;
  8. @end
  9. @implementation ViewController
  10. - (CALayer *)faceWithTransform:(CATransform3D)transform
  11. {
  12. //create cube face layer
  13. CALayer *face = [CALayer layer];
  14. face.frame = CGRectMake(-50, -50, 100, 100);
  15. //apply a random color
  16. CGFloat red = (rand() / (double)INT_MAX);
  17. CGFloat green = (rand() / (double)INT_MAX);
  18. CGFloat blue = (rand() / (double)INT_MAX);
  19. face.backgroundColor = [UIColor colorWithRed:red
  20. green:green
  21. blue:blue
  22. alpha:1.0].CGColor;
  23. //apply the transform and return
  24. face.transform = transform;
  25. return face;
  26. }
  27. - (CALayer *)cubeWithTransform:(CATransform3D)transform
  28. {
  29. //create cube layer
  30. CATransformLayer *cube = [CATransformLayer layer];
  31. //add cube face 1
  32. CATransform3D ct = CATransform3DMakeTranslation(0, 0, 50);
  33. [cube addSublayer:[self faceWithTransform:ct]];
  34. //add cube face 2
  35. ct = CATransform3DMakeTranslation(50, 0, 0);
  36. ct = CATransform3DRotate(ct, M_PI_2, 0, 1, 0);
  37. [cube addSublayer:[self faceWithTransform:ct]];
  38. //add cube face 3
  39. ct = CATransform3DMakeTranslation(0, -50, 0);
  40. ct = CATransform3DRotate(ct, M_PI_2, 1, 0, 0);
  41. [cube addSublayer:[self faceWithTransform:ct]];
  42. //add cube face 4
  43. ct = CATransform3DMakeTranslation(0, 50, 0);
  44. ct = CATransform3DRotate(ct, -M_PI_2, 1, 0, 0);
  45. [cube addSublayer:[self faceWithTransform:ct]];
  46. //add cube face 5
  47. ct = CATransform3DMakeTranslation(-50, 0, 0);
  48. ct = CATransform3DRotate(ct, -M_PI_2, 0, 1, 0);
  49. [cube addSublayer:[self faceWithTransform:ct]];
  50. //add cube face 6
  51. ct = CATransform3DMakeTranslation(0, 0, -50);
  52. ct = CATransform3DRotate(ct, M_PI, 0, 1, 0);
  53. [cube addSublayer:[self faceWithTransform:ct]];
  54. //center the cube layer within the container
  55. CGSize containerSize = self.containerView.bounds.size;
  56. cube.position = CGPointMake(containerSize.width / 2.0,
  57. containerSize.height / 2.0);
  58. //apply the transform and return
  59. cube.transform = transform;
  60. return cube;
  61. }
  62. - (void)viewDidLoad
  63. {
  64. [super viewDidLoad];
  65. //set up the perspective transform
  66. CATransform3D pt = CATransform3DIdentity;
  67. pt.m34 = -1.0 / 500.0;
  68. self.containerView.layer.sublayerTransform = pt;
  69. //set up the transform for cube 1 and add it
  70. CATransform3D c1t = CATransform3DIdentity;
  71. c1t = CATransform3DTranslate(c1t, -100, 0, 0);
  72. CALayer *cube1 = [self cubeWithTransform:c1t];
  73. s_Cube = (CATransformLayer *)cube1;
  74. [self.containerView.layer addSublayer:cube1];
  75. //set up the transform for cube 2 and add it
  76. CATransform3D c2t = CATransform3DIdentity;
  77. c2t = CATransform3DTranslate(c2t, 100, 0, 0);
  78. c2t = CATransform3DRotate(c2t, -M_PI_4, 1, 0, 0);
  79. c2t = CATransform3DRotate(c2t, -M_PI_4, 0, 1, 0);
  80. CALayer *cube2 = [self cubeWithTransform:c2t];
  81. [self.containerView.layer addSublayer:cube2];
  82. }
  83. - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
  84. {
  85. UITouch *touch = [touches anyObject];
  86. startPoint = [touch locationInView:self.view];
  87. }
  88. - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
  89. {
  90. UITouch *touch = [touches anyObject];
  91. CGPoint currentPosition = [touch locationInView:self.view];
  92. CGFloat deltaX = startPoint.x - currentPosition.x;
  93. CGFloat deltaY = startPoint.y - currentPosition.y;
  94. CATransform3D c1t = CATransform3DIdentity;
  95. c1t = CATransform3DTranslate(c1t, -100, 0, 0);
  96. c1t = CATransform3DRotate(c1t, pix+M_PI_2*deltaY/100, 1, 0, 0);
  97. c1t = CATransform3DRotate(c1t, piy-M_PI_2*deltaX/100, 0, 1, 0);
  98. s_Cube.transform = c1t;
  99. }
  100. - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
  101. {
  102. UITouch *touch = [touches anyObject];
  103. CGPoint currentPosition = [touch locationInView:self.view];
  104. CGFloat deltaX = startPoint.x - currentPosition.x;
  105. CGFloat deltaY = startPoint.y - currentPosition.y;
  106. pix = M_PI_2*deltaY/100;
  107. piy = -M_PI_2*deltaX/100;
  108. }
  109. @end

IOS Core Animation Advanced Techniques的学习笔记(五)

 
 
 
 
CAGradientLayer
 
产生平滑过渡色,
 

例子6.6

  1. interface ViewController ()
  2. @property (nonatomic, weak) IBOutlet UIView *containerView;
  3. @end
  4. @implementation ViewController
  5. - (void)viewDidLoad
  6. {
  7. [super viewDidLoad];
  8. //create gradient layer and add it to our container view
  9. CAGradientLayer *gradientLayer = [CAGradientLayer layer];
  10. gradientLayer.frame = self.containerView.bounds;
  11. [self.containerView.layer addSublayer:gradientLayer];
  12. //set gradient colors
  13. gradientLayer.colors = @[(__bridge id)[UIColor redColor].CGColor,
  14. (__bridge id)[UIColor blueColor].CGColor];
  15. //set gradient start and end points
  16. gradientLayer.startPoint = CGPointMake(0, 0);
  17. gradientLayer.endPoint = CGPointMake(1, 1);
  18. }
  19. @end

IOS Core Animation Advanced Techniques的学习笔记(五)

 

CAGradientLayer的属性设置

1. 类型
  1. @property(copy) NSString *type

目前只有NSString * const kCAGradientLayerAxial
即线性梯度变化

2. 颜色
  1. @property(copy) NSArray *colors

3. 位置参数

  1. @property(copy) NSArray *locations

颜色的区间分布,locations的数组长度和colors一致, 取值范围(0, 1),而且必须是单调递增的

 
修改例子6.6,增加
  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的学习笔记(五)

  1. gradientLayer.locations = @[[NSNumber numberWithFloat:0.5], [NSNumber numberWithFloat:0.7]];

IOS Core Animation Advanced Techniques的学习笔记(五)

 
4. startPoint和endPoint
  1. @property CGPoint startPoint, endPoint;
取值都是相对于layer的bounds的。startPoint默认值为(0.5, 0),endPoint默认值为(0.5, 1)
 

修改例子6.6

gradientLayer.startPoint 分别设为 CGPointMake(0, 0);

IOS Core Animation Advanced Techniques的学习笔记(五)

 
 CGPointMake(0.25, 0); 
IOS Core Animation Advanced Techniques的学习笔记(五)
 
 CGPointMake(0.5, 0); 
IOS Core Animation Advanced Techniques的学习笔记(五)
 
 CGPointMake(0.75, 0); 
IOS Core Animation Advanced Techniques的学习笔记(五)
 
 CGPointMake(1, 0); 
IOS Core Animation Advanced Techniques的学习笔记(五)
 
 
综合修改例子6.6
  1. - (void)viewDidLoad
  2. {
  3. [super viewDidLoad];
  4. //create gradient layer and add it to our container view
  5. CAGradientLayer *gradientLayer = [CAGradientLayer layer];
  6. gradientLayer.frame = self.containerView.bounds;
  7. [self.containerView.layer addSublayer:gradientLayer];
  8. //set gradient colors
  9. gradientLayer.colors = @[(__bridge id)[UIColor redColor].CGColor,
  10. (__bridge id)[UIColor blueColor].CGColor];
  11. gradientLayer.locations = @[[NSNumber numberWithFloat:0.5], [NSNumber numberWithFloat:0.7]];
  12. //set gradient start and end points
  13. gradientLayer.startPoint = CGPointMake(0.75, 0.0);
  14. gradientLayer.endPoint = CGPointMake(1.0, 1.0);
  15. }

IOS Core Animation Advanced Techniques的学习笔记(五)

 
从以上可以看出startPoint和endPoint诗表示的渐变方向,locations是渐变区域。
也可以看出locations的取值是相对于startPoint和endPoint线段的。
 
在网上找的描述让我很是不能理解
 
IOS Core Animation Advanced Techniques的学习笔记(五)
 
 
CAReplicatorLayer
 
例子6.8,修改一下看得更清楚些
  1. @interface ViewController ()
  2. @property (nonatomic, weak) IBOutlet UIView *containerView;
  3. @end
  4. @implementation ViewController
  5. - (void)viewDidLoad
  6. {
  7. [super viewDidLoad];
  8. //create a replicator layer and add it to our view
  9. CAReplicatorLayer *replicator = [CAReplicatorLayer layer];
  10. replicator.frame = self.containerView.bounds;
  11. [self.containerView.layer addSublayer:replicator];
  12. //configure the replicator
  13. replicator.instanceCount = 20;
  14. //apply a transform for each instance
  15. CATransform3D transform = CATransform3DIdentity;
  16. transform = CATransform3DTranslate(transform, 0, -10, 0);
  17. transform = CATransform3DRotate(transform, M_PI / 10.0, 0, 0, 1);
  18. transform = CATransform3DTranslate(transform, 0, 10, 0);
  19. replicator.instanceTransform = transform;
  20. //apply a color shift for each instance
  21. replicator.instanceBlueOffset = -0.1;
  22. replicator.instanceGreenOffset = -0.1;
  23. //create a sublayer and place it inside the replicator
  24. CALayer *layer = [CALayer layer];
  25. layer.frame = CGRectMake(137.5f, 25.0f, 25.0f, 25.0f);
  26. layer.backgroundColor = [UIColor whiteColor].CGColor;
  27. [replicator addSublayer:layer];
  28. }
  29. @end

IOS Core Animation Advanced Techniques的学习笔记(五)

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

 
 
后面的几个特殊layer我就不在这里列举了,自己去研究吧
 
下一次,就将进入真正的动画部分了
上一篇:IOS Core Animation Advanced Techniques的学习笔记(一)


下一篇:iOS Instruments之Core Animation动画性能调优(工具复选框选项介绍)