16/04/28 第六章 专用图层
CAShapeLayer
CAShapeLayer
是一个通过矢量图形绘制的图层子类,而非bitmap.- 通过
CAShapeLayer
来绘制相比于Core Graphics
而言优点在于:- 渲染快速,
CAShapeLayer
使用了硬件加速,绘制同一图形比Core Graphics
快.
- 搞笑使用内存,一个
CAShapeLayer
不需要像普通CALayer
一样创建一个寄宿图形,所以无论有多大,都不会占用太多的内存. 矢量.
- 不会被图层边界裁剪,一个
CAShapeLayer
可以在边界之外绘制。你的图层路径不会像在使用Core Graphics
的普通CALayer
一样被剪裁掉.
- 不会出现像素化(矢量).当你给
CAShapeLayer
做3D变换时,它不像一个有寄宿图的普通图层一样变得像素化。
- 渲染快速,
-
创建一个CGPath
- 部分属性:
- lineWith: 线宽,用点表示单位
- lineCap: 线条结尾的样子
- lineJoin: 线条之间的结合点的样子
- 可在同一图层绘制多个形状, 但只有一次机会设置属性,若需颜色不同,则要为每个形状准备一个图层.
-
圆角
通过
UIBezierPath
绘制自定义圆角个数的矩形:1
2
3
4
5
6
7
8
9
10
11
12
13
14//设置规则
CGRect rect = CGRectMake(50, 50, 100, 100);
CGSize radii = CGSizeMake(20, 20);
UIRectCorner corners = UIRectCornerTopRight | UIRectCornerBottomRight | UIRectCornerBottomLeft;
//创建被三儿路径
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:corners cornerRadii:radii];
// 设置ShapeLayer
CAShapeLayer *shapeLayer = [CAShapeLayer alloc]init];
shapeLayer.lineWidth = 3;
shapeLayer.lineCap = kCALineCapRound;
shapeLayer.lineJoin = kCALineJoinRound;
shapeLayer.path = path.CGPath;
-
CATextLayer
Core Animation
提供了一个CALayer
的子类CATextLayer
,以图层的形式包含了UILabel
几乎所有的绘制特性, 并额外提供了一些新的特性.- 性能上,
CATextLayer
比UILabel
快很多.CATextLayer
使用了Core Text
. - iOS6之前,
UILabel
通过WebKit
来实现绘制? 用CATextLayer来实现一个UILabel:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39@interface ViewController ()
@property (nonatomic, weak) IBOutlet UIView *labelView;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//创建TextLayer添加
CATextLayer *textLayer = [CATextLayer layer];
textLayer.frame = self.labelView.bounds;
[self.labelView.layer addSublayer:textLayer];
//设置字体颜色
textLayer.foregroundColor = [UIColor blackColor].CGColor;
//设置对齐方式
textLayer.alignmentMode = kCAAlignmentJustified;
textLayer.wrapped = YES;
UIFont *font = [UIFont systemFontOfSize:15];
//设置字体
CFStringRef fontName = (__bridge CFStringRef)font.fontName;
CGFontRef fontRef = CGFontCreateWithFontName(fontName);
textLayer.font = fontRef;
//设置字体大小
textLayer.fontSize = font.pointSize;
CGFontRelease(fontRef);
//设置文本内容
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";
//赋值
textLayer.string = text;
}
@end当这样设置后,显示会出现像素化,需要以当前屏幕的Scale来显示:
textLayer.contentsScale = [UIScreen mainScreen].scale;
CATextLayer
的font
属性为CFTypeRef
类型, 可根据具体需求设置为CGFontRef
或CTFontRef
.- 字体大小由单独的
fontSize
决定, 因上述CTFontRef
和CGFontRef
并不像UIFont
一样包含点大小. CATextLayer
的string
属性为id
类型,这样既可用NSString
也可用富文本NSAttributedString
了.
富文本
字符属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25字符属性可以应用于 attributed string 的文本中。
NSString *const NSFontAttributeName;(字体)
NSString *const NSParagraphStyleAttributeName;(段落)
NSString *const NSForegroundColorAttributeName;(字体颜色)
NSString *const NSBackgroundColorAttributeName;(字体背景色)
NSString *const NSLigatureAttributeName;(连字符)
NSString *const NSKernAttributeName;(字间距)
NSString *const NSStrikethroughStyleAttributeName;(删除线)
NSString *const NSUnderlineStyleAttributeName;(下划线)
NSString *const NSStrokeColorAttributeName;(边线颜色)
NSString *const NSStrokeWidthAttributeName;(边线宽度)
NSString *const NSShadowAttributeName;(阴影)(横竖排版)
NSString *const NSVerticalGlyphFormAttributeName;
常量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
471> NSFontAttributeName(字体)
该属性所对应的值是一个 UIFont 对象。该属性用于改变一段文本的字体。如果不指定该属性,则默认为12-point Helvetica(Neue)。
2> NSParagraphStyleAttributeName(段落)
该属性所对应的值是一个 NSParagraphStyle 对象。该属性在一段文本上应用多个属性。如果不指定该属性,则默认为 NSParagraphStyle 的defaultParagraphStyle 方法返回的默认段落属性。
3> NSForegroundColorAttributeName(字体颜色)
该属性所对应的值是一个 UIColor 对象。该属性用于指定一段文本的字体颜色。如果不指定该属性,则默认为黑色。
4> NSBackgroundColorAttributeName(字体背景色)
该属性所对应的值是一个 UIColor 对象。该属性用于指定一段文本的背景颜色。如果不指定该属性,则默认无背景色。
5> NSLigatureAttributeName(连字符)
该属性所对应的值是一个 NSNumber 对象(整数)。连体字符是指某些连在一起的字符,它们采用单个的图元符号。0 表示没有连体字符。1 表示使用默认的连体字符。2表示使用所有连体符号。默认值为 1(注意,iOS 不支持值为 2)。
6> NSKernAttributeName(字间距)
该属性所对应的值是一个 NSNumber 对象(整数)。字母紧排指定了用于调整字距的像素点数。字母紧排的效果依赖于字体。值为 0 表示不使用字母紧排。默认值为0。
7> NSStrikethroughStyleAttributeName(删除线)
该属性所对应的值是一个 NSNumber 对象(整数)。该值指定是否在文字上加上删除线,该值参考“Underline Style Attributes”。默认值是NSUnderlineStyleNone。
8> NSUnderlineStyleAttributeName(下划线)
该属性所对应的值是一个 NSNumber 对象(整数)。该值指定是否在文字上加上下划线,该值参考“Underline Style Attributes”。默认值是NSUnderlineStyleNone。
9> NSStrokeColorAttributeName(边线颜色)
该属性所对应的值是一个 UIColor 对象。如果该属性不指定(默认),则等同于 NSForegroundColorAttributeName。否则,指定为删除线或下划线颜色。更多细节见“Drawing attributedstrings that are both filled and stroked”。
10> NSStrokeWidthAttributeName(边线宽度)
该属性所对应的值是一个 NSNumber 对象(小数)。该值改变描边宽度(相对于字体size 的百分比)。默认为 0,即不改变。正数只改变描边宽度。负数同时改变文字的描边和填充宽度。例如,对于常见的空心字,这个值通常为3.0。
11> NSShadowAttributeName(阴影)
该属性所对应的值是一个 NSShadow 对象。默认为 nil。
12> NSVerticalGlyphFormAttributeName(横竖排版)
该属性所对应的值是一个 NSNumber 对象(整数)。0 表示横排文本。1 表示竖排文本。在 iOS 中,总是使用横排文本,0 以外的值都未定义。
UILabel的替代品
可以通过重写View的类方法
+ (Class)layerClass
来将UILabel替换成CATextLayer;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#import "LayerLabel.h"
#import <QuartzCore/QuartzCore.h>
@implementation LayerLabel
+ (Class)layerClass
{
//this makes our label create a CATextLayer //instead of a regular CALayer for its backing layer
return [CATextLayer class];
}
- (CATextLayer *)textLayer
{
return (CATextLayer *)self.layer;
}
- (void)setUp
{
//set defaults from UILabel settings
self.text = self.text;
self.textColor = self.textColor;
self.font = self.font;
//we should really derive these from the UILabel settings too
//but that's complicated, so for now we'll just hard-code them
[self textLayer].alignmentMode = kCAAlignmentJustified;

[self textLayer].wrapped = YES;
[self.layer display];
}
- (id)initWithFrame:(CGRect)frame
{
//called when creating label programmatically
if (self = [super initWithFrame:frame]) {
[self setUp];
}
return self;
}
- (void)awakeFromNib
{
//called when creating label using Interface Builder
[self setUp];
}
- (void)setText:(NSString *)text
{
super.text = text;
//set layer text
[self textLayer].string = text;
}
- (void)setTextColor:(UIColor *)textColor
{
super.textColor = textColor;
//set layer text color
[self textLayer].foregroundColor = textColor.CGColor;
}
- (void)setFont:(UIFont *)font
{
super.font = font;
//set layer font
CFStringRef fontName = (__bridge CFStringRef)font.fontName;
CGFontRef fontRef = CGFontCreateWithFontName(fontName);
[self textLayer].font = fontRef;
[self textLayer].fontSize = font.pointSize;

CGFontRelease(fontRef);
}
@end