iOS专用图层解析

CAShapeLayer

CAShapeLayer是一个通过矢量图形而不是bitmap来绘制的图层子类。你指定诸如颜色和线宽等属性,用CGPath来定义想要绘制的图形,最后CAShapeLayer就自动渲染出来了。当然,你也可以用Core Graphics直接向原始的CALyer的内容中绘制一个路径,相比直下,使用CAShapeLayer有以下一些优点:

  • 渲染快速。
  • 高效使用内存。
  • 不会被图层边界剪裁掉。
  • 不会出现像素化。

创建一个path画一个圆

 UIBezierPath *path = [[UIBezierPath alloc] init];
        [path addArcWithCenter:CGPointMake(100, 100) radius:25 startAngle:0 endAngle:2*M_PI clockwise:YES];
        
        CAShapeLayer *shapeLayer = [CAShapeLayer layer];
        shapeLayer.strokeColor = [UIColor redColor].CGColor;
        shapeLayer.fillColor = [UIColor clearColor].CGColor;
        shapeLayer.lineWidth = 5;
        shapeLayer.lineJoin = kCALineJoinRound;
        shapeLayer.lineCap = kCALineCapRound;
        shapeLayer.path = path.CGPath;
        //add it to our view
        [self.layer addSublayer:shapeLayer];
iOS专用图层解析_第1张图片
E77C36FF-D39B-4C59-B6D2-273B72E45533.png

还可以利用CAShapeLayer画一些不规则图形

CAShapeLayer为创建圆角视图提供了一个方法,就是CALayercornerRadius属性。虽然使用CAShapeLayer类需要更多的工作,但是它有一个优势就是可以单独指定每个角。

       //define path parameters
        CGRect rect = CGRectMake(50, 50, 100, 100);
        CGSize radii = CGSizeMake(20, 20);
        UIRectCorner corners = UIRectCornerTopRight | UIRectCornerBottomRight | UIRectCornerBottomLeft;
        //create path
        UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:corners cornerRadii:radii];        
        CAShapeLayer *shapeLayer = [CAShapeLayer layer];
        shapeLayer.strokeColor = [UIColor redColor].CGColor;
        shapeLayer.fillColor = [UIColor clearColor].CGColor;
        shapeLayer.lineWidth = 5;
        shapeLayer.lineJoin = kCALineJoinRound;
        shapeLayer.lineCap = kCALineCapRound;
        shapeLayer.path = path.CGPath;
        //add it to our view
        [self.layer addSublayer:shapeLayer];
iOS专用图层解析_第2张图片
24A5C5BB-DF86-44B2-991A-FFB1375D854A.png

CATextLayer

CATextLayer是CALayer的子类,它以图层的形式包含了UILabel几乎所有的绘制特性,并且额外的提供了一些新的特性,并且额外的提供了一些新的特性。同样CATextLayerUILabel渲染得快得多。

尝试用CATextLayer实现一个UILabel的功能

        CATextLayer *textLayer = [CATextLayer layer];
        textLayer.frame = self.bounds;
        //此处要注意设置Layer的比例,不然字看起来会失帧
        textLayer.contentsScale = [UIScreen mainScreen].scale;
        [self.layer addSublayer:textLayer];
        
        //set text attributes
        textLayer.foregroundColor = [UIColor blackColor].CGColor;
        textLayer.alignmentMode = kCAAlignmentJustified;
        textLayer.wrapped = YES;
        
        //choose a font
        UIFont *font = [UIFont systemFontOfSize:15];
        
        //set layer font
        CFStringRef fontName = (__bridge CFStringRef)font.fontName;
        CGFontRef fontRef = CGFontCreateWithFontName(fontName);
        textLayer.font = fontRef;
        textLayer.fontSize = font.pointSize;
        CGFontRelease(fontRef);
        
        textLayer.string = text;

CATextLayerfont属性不是一个UIFont类型,而是一个CFTypeRef类型。这样可以根据你的具体需要来决定字体属性应该是用CGFontRef类型还是CTFontRef类型(Core Text字体)。同时字体大小也是用fontSize属性单独设置的,因为CTFontRefCGFontRef并不像UIFont一样包含点大小。这个例子会告诉你如何将UIFont转换成CGFontRef
另外,CATextLayerstring属性并不是你想象的NSString类型,而是id类型。这样你既可以用NSString也可以用NSAttributedString来指定文本了(注意,NSAttributedString并不是NSString的子类)。属性化字符串是iOS用来渲染字体风格的机制,它以特定的方式来决定指定范围内的字符串的原始信息,比如字体,颜色,字重,斜体等。

富文本

让我们编辑一下示例使用到NSAttributedString.iOS 6及以上我们可以用新的NSTextAttributeName实例来设置我们的字符串属性,但是练习的目的是为了演示在iOS 5及以下,所以我们用了Core Text,也就是说你需要把Core Text framework添加到你的项目中。否则,编译器是无法识别属性常量的。

 //create a text layer
  CATextLayer *textLayer = [CATextLayer layer];
  textLayer.frame = self.labelView.bounds;
  textLayer.contentsScale = [UIScreen mainScreen].scale;
  [self.labelView.layer addSublayer:textLayer];

  //set text attributes
  textLayer.alignmentMode = kCAAlignmentJustified;
  textLayer.wrapped = YES;

  //choose a font
  UIFont *font = [UIFont systemFontOfSize:15];

  //choose some text
  NSString *text = @"Lorem ipsum dolor sit amet, consectetur adipiscing \ elit. Quisque massa arcu, eleifend vel varius in, facilisis pulvinar \ leo. Nunc quis nunc at mauris pharetra condimentum ut ac neque. Nunc \ elementum, libero ut porttitor dictum, diam odio congue lacus, vel \ fringilla sapien diam at purus. Etiam suscipit pretium nunc sit amet \ lobortis";
  
  //create attributed string
  NSMutableAttributedString *string = nil;
  string = [[NSMutableAttributedString alloc] initWithString:text];

  //convert UIFont to a CTFont
  CFStringRef fontName = (__bridge CFStringRef)font.fontName;
  CGFloat fontSize = font.pointSize;
  CTFontRef fontRef = CTFontCreateWithName(fontName, fontSize, NULL);

  //set text attributes
  NSDictionary *attribs = @{
    (__bridge id)kCTForegroundColorAttributeName:(__bridge id)[UIColor blackColor].CGColor,
    (__bridge id)kCTFontAttributeName: (__bridge id)fontRef
  };

  [string setAttributes:attribs range:NSMakeRange(0, [text length])];
  attribs = @{
    (__bridge id)kCTForegroundColorAttributeName: (__bridge id)[UIColor redColor].CGColor,
    (__bridge id)kCTUnderlineStyleAttributeName: @(kCTUnderlineStyleSingle),
    (__bridge id)kCTFontAttributeName: (__bridge id)fontRef
  };
  [string setAttributes:attribs range:NSMakeRange(6, 5)];

  //release the CTFont we created earlier
  CFRelease(fontRef);

  //set layer text
  textLayer.string = string;
}
@end

未完....

你可能感兴趣的:(iOS专用图层解析)