CAShapeLayer
CAShapeLayer
是一个通过矢量图形而不是bitmap来绘制的图层子类。你指定诸如颜色和线宽等属性,用CGPath
来定义想要绘制的图形,最后CAShapeLaye
r就自动渲染出来了。当然,你也可以用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];
还可以利用CAShapeLayer画一些不规则图形
CAShapeLayer
为创建圆角视图提供了一个方法,就是CALayer
的cornerRadius
属性。虽然使用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];
CATextLayer
CATextLayer
是CALayer的子类,它以图层的形式包含了UILabel
几乎所有的绘制特性,并且额外的提供了一些新的特性,并且额外的提供了一些新的特性。同样CATextLayer
比UILabel
渲染得快得多。
尝试用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;
CATextLayer
的font
属性不是一个UIFont类型,而是一个CFTypeRef
类型。这样可以根据你的具体需要来决定字体属性应该是用CGFontRef
类型还是CTFontRef
类型(Core Text
字体)。同时字体大小也是用fontSize属性单独设置的,因为CTFontRef
和CGFontRef
并不像UIFont
一样包含点大小。这个例子会告诉你如何将UIFont
转换成CGFontRef
。
另外,CATextLayer
的string
属性并不是你想象的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
未完....