• 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.   
    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(175, 100)];  
    16.     [path addArcWithCenter:CGPointMake(150, 100) radius:25 startAngle:0 endAngle:2*M_PI clockwise:YES];  
    17.     [path moveToPoint:CGPointMake(150, 125)];  
    18.     [path addLineToPoint:CGPointMake(150, 175)];  
    19.     [path addLineToPoint:CGPointMake(125, 225)];  
    20.     [path moveToPoint:CGPointMake(150, 175)];  
    21.     [path addLineToPoint:CGPointMake(175, 225)];  
    22.     [path moveToPoint:CGPointMake(100, 150)];  
    23.     [path addLineToPoint:CGPointMake(200, 150)];  
    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  


     
     
    先说说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.       
    5.     //create path  
    6.     UIBezierPath *path = [[UIBezierPath alloc] init];  
    7.     [path moveToPoint:CGPointMake(200, 150)];  
    8.     [path addArcWithCenter:CGPointMake(150, 150) radius:50 startAngle:0 endAngle:2*M_PI clockwise:YES];  
    9.     [path moveToPoint:CGPointMake(250, 150)];  
    10.     [path addArcWithCenter:CGPointMake(150, 150) 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. }  

    再修改
    1. - (void)viewDidLoad  
    2. {  
    3.     [super viewDidLoad];  
    4.       
    5.     //create path  
    6.     UIBezierPath *path = [[UIBezierPath alloc] init];  
    7.     [path moveToPoint:CGPointMake(200, 150)];  
    8.     [path addArcWithCenter:CGPointMake(150, 150) radius:50 startAngle:0 endAngle:2*M_PI clockwise:YES];  
    9.     [path moveToPoint:CGPointMake(250, 150)];  
    10.     [path addArcWithCenter:CGPointMake(150, 150) 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. }  


     

    kCAFillRuleEvenOdd的情况

    修改代码
    1. - (void)viewDidLoad  
    2. {  
    3.     [super viewDidLoad];  
    4.       
    5.     //create path  
    6.     UIBezierPath *path = [[UIBezierPath alloc] init];  
    7.     [path moveToPoint:CGPointMake(200, 150)];  
    8.     [path addArcWithCenter:CGPointMake(150, 150) radius:50 startAngle:0 endAngle:2*M_PI clockwise:YES];  
    9.     [path moveToPoint:CGPointMake(250, 150)];  
    10.     [path addArcWithCenter:CGPointMake(150, 150) 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. }  


     
    同样修改
    1. - (void)viewDidLoad  
    2. {  
    3.     [super viewDidLoad];  
    4.       
    5.     //create path  
    6.     UIBezierPath *path = [[UIBezierPath alloc] init];  
    7.     [path moveToPoint:CGPointMake(200, 150)];  
    8.     [path addArcWithCenter:CGPointMake(150, 150) radius:50 startAngle:0 endAngle:2*M_PI clockwise:YES];  
    9.     [path moveToPoint:CGPointMake(250, 150)];  
    10.     [path addArcWithCenter:CGPointMake(150, 150) 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. }  

    继续为了看清奇偶的效果,画3个同方向圆圈
     
    1. - (void)viewDidLoad  
    2. {  
    3.     [super viewDidLoad];  
    4.       
    5.     //create path  
    6.     UIBezierPath *path = [[UIBezierPath alloc] init];  
    7.     [path moveToPoint:CGPointMake(200, 150)];  
    8.     [path addArcWithCenter:CGPointMake(150, 150) radius:50 startAngle:0 endAngle:2*M_PI clockwise:YES];  
    9.     [path moveToPoint:CGPointMake(250, 150)];  
    10.     [path addArcWithCenter:CGPointMake(150, 150) radius:100 startAngle:0 endAngle:2*M_PI clockwise:YES];  
    11.     [path moveToPoint:CGPointMake(300, 150)];  
    12.     [path addArcWithCenter:CGPointMake(150, 150) 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. }  


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

    evenodd字面意思是“奇偶”。按该规则,要判断一个点是否在图形内,从该点作任意方向的一条射线,然后检测射线与图形路径的交点的数量。如果结果是奇数则认为点在内部,是偶数则认为点在外部。下图演示了evenodd 规则:
     
    4. 线端点类型
    1. @property(copy) NSString *lineCap  


    5. 线连接类型
    1. @property(copy) NSString *lineJoin  
     
    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.   
    5.     //create path  
    6.     UIBezierPath *path = [[UIBezierPath alloc] init];  
    7.     [path moveToPoint:CGPointMake(175, 100)];  
    8.     [path addArcWithCenter:CGPointMake(150, 100) radius:25 startAngle:0 endAngle:2*M_PI clockwise:YES];  
    9.     [path moveToPoint:CGPointMake(150, 125)];  
    10.     [path addLineToPoint:CGPointMake(150, 175)];  
    11.     [path addLineToPoint:CGPointMake(125, 225)];  
    12.     [path moveToPoint:CGPointMake(150, 175)];  
    13.     [path addLineToPoint:CGPointMake(175, 225)];  
    14.     [path moveToPoint:CGPointMake(100, 150)];  
    15.     [path addLineToPoint:CGPointMake(200, 150)];  
    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. }  

    再修改lineDashPhase值=15



     

    9. 最大斜接长度。

     

    1. @property CGFloat miterLimit  

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

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

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

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

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

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

    都是0.0~1.0的取值范围
    具体看修改例子6.1
    1. - (void)viewDidLoad  
    2. {  
    3.     [super viewDidLoad];  
    4.   
    5.     //create path  
    6.     UIBezierPath *path = [[UIBezierPath alloc] init];  
    7.     [path moveToPoint:CGPointMake(175, 100)];  
    8.     [path addArcWithCenter:CGPointMake(150, 100) radius:25 startAngle:0 endAngle:2*M_PI clockwise:YES];  
    9.     [path moveToPoint:CGPointMake(150, 125)];  
    10.     [path addLineToPoint:CGPointMake(150, 175)];  
    11.     [path addLineToPoint:CGPointMake(125, 225)];  
    12.     [path moveToPoint:CGPointMake(150, 175)];  
    13.     [path addLineToPoint:CGPointMake(175, 225)];  
    14.     [path moveToPoint:CGPointMake(100, 150)];  
    15.     [path addLineToPoint:CGPointMake(200, 150)];  
    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. }  


     
     
    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  
     


     
    以下需要配合moveToPoint使用
    1. - (void)moveToPoint:(CGPoint)point  
     
    6. 直线
    1. - (void)addLineToPoint:(CGPoint)point  

    7. 曲线
    1. - (void)addCurveToPoint:(CGPoint)endPoint controlPoint1:(CGPoint)controlPoint1 controlPoint2:(CGPoint)controlPoint2  
     
    8. 二元曲线
    1. - (void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint  


    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.   
    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  

    仔细看文字周围很模糊,解决这个问题需要设置contentsScale
     
    修改“textLayer.contentsScale = [UIScreen mainScreen].scale;”


     
     
    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.   
    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, -50, 100, 100);  
    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(0, 0, 50);  
    43.     [cube addSublayer:[self faceWithTransform:ct]];  
    44.       
    45.     //add cube face 2  
    46.     ct = CATransform3DMakeTranslation(50, 0, 0);  
    47.     ct = CATransform3DRotate(ct, M_PI_2, 0, 1, 0);  
    48.     [cube addSublayer:[self faceWithTransform:ct]];  
    49.       
    50.     //add cube face 3  
    51.     ct = CATransform3DMakeTranslation(0, -50, 0);  
    52.     ct = CATransform3DRotate(ct, M_PI_2, 1, 0, 0);  
    53.     [cube addSublayer:[self faceWithTransform:ct]];  
    54.       
    55.     //add cube face 4  
    56.     ct = CATransform3DMakeTranslation(0, 50, 0);  
    57.     ct = CATransform3DRotate(ct, -M_PI_2, 1, 0, 0);  
    58.     [cube addSublayer:[self faceWithTransform:ct]];  
    59.       
    60.     //add cube face 5  
    61.     ct = CATransform3DMakeTranslation(-50, 0, 0);  
    62.     ct = CATransform3DRotate(ct, -M_PI_2, 0, 1, 0);  
    63.     [cube addSublayer:[self faceWithTransform:ct]];  
    64.       
    65.     //add cube face 6  
    66.     ct = CATransform3DMakeTranslation(0, 0, -50);  
    67.     ct = CATransform3DRotate(ct, M_PI, 0, 1, 0);  
    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, -100, 0, 0);  
    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, 100, 0, 0);  
    99.     c2t = CATransform3DRotate(c2t, -M_PI_4, 1, 0, 0);  
    100.     c2t = CATransform3DRotate(c2t, -M_PI_4, 0, 1, 0);  
    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, -100, 0, 0);  
    124.     c1t = CATransform3DRotate(c1t, pix+M_PI_2*deltaY/100, 1, 0, 0);  
    125.     c1t = CATransform3DRotate(c1t, piy-M_PI_2*deltaX/100, 0, 1, 0);  
    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  


     
     
     
     
    CAGradientLayer
     
    产生平滑过渡色,
     
    例子6.6
    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(0, 0);  
    24.     gradientLayer.endPoint = CGPointMake(1, 1);      
    25. }  
    26.   
    27. @end  


     

    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>  

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


     
    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); 

     
     CGPointMake(0.25, 0); 
     
     CGPointMake(0.5, 0); 
     
     CGPointMake(0.75, 0); 
     
     CGPointMake(1, 0); 
     
     
    综合修改例子6.6
    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.75, 0.0);  
    18.     gradientLayer.endPoint = CGPointMake(1.0, 1.0);  
    19. }  


     
    从以上可以看出startPoint和endPoint诗表示的渐变方向,locations是渐变区域。
    也可以看出locations的取值是相对于startPoint和endPoint线段的。
     
    在网上找的描述让我很是不能理解
     
     
     
    CAReplicatorLayer
     
    例子6.8,修改一下看得更清楚些
    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, -10, 0);  
    24.     transform = CATransform3DRotate(transform, M_PI / 10.0, 0, 0, 1);  
    25.     transform = CATransform3DTranslate(transform, 0, 10, 0);  
    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.5f, 25.0f, 25.0f, 25.0f);  
    35.     layer.backgroundColor = [UIColor whiteColor].CGColor;  
    36.     [replicator addSublayer:layer];  
    37. }  
    38.   
    39. @end  

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

     
     
    后面的几个特殊layer我就不在这里列举了,自己去研究吧
     
    下一次,就将进入真正的动画部分了
  • 相关阅读:
    laravel进阶知识大纲
    spring boot 配置多个DispatcherServlet
    RepeatReadRequestWrapper
    RestTemplate HttpClient详解及如何设置忽略SSL
    Swagger注解-@ApiModel 和 @ApiModelProperty
    SpringBoot 接收 单个String入参之解决方案
    spring boot添加 LocalDateTime 等 java8 时间类序列化和反序列化的支持
    Mybatisplus实现MetaObjectHandler接口自动更新创建时间更新时间
    关于SpringBoot 2.0,Pageable 无法注入,提示缺少默认构造方法的解决办法
    OP_REQUIRES failed at save_restore_v2_ops.cc:109 : Permission denied: model/variables/variables_t emp; Permission denied
  • 原文地址:https://www.cnblogs.com/lzlsky/p/4011826.html
Copyright © 2020-2023  润新知