UILabel 文档: https://developer.apple.com/reference/uikit/uilabel#overview
UILabel继承自UIView,显示多行只读文本。可以显示普通文本和富文本,两个都设置的话,会显示最后设置的内容。
<p>
在故事板设置的属性
Attribute text
在故事板中设置attribute text。如图attribute text所示,首先从Plain切换到Attributed,选中字符,比如“L”,然后设置字体颜色和背景色。In Attributed mode, select a part of the string and use the color cell to set the color of the selection.
label的对齐方式,you can control the alignment of individual paragraphs. 独立的段落的对齐方式可以不同??
Spaceing
设置行间距:点击...,在弹出的窗口中,Spaceing表示行间距。
Line = 0 表示多行显示,use as many lines as required。
Behavior
设置label的行为:Enable和Hightlighted。Enable禁用时文字是暗色的,没有其他作用。而isUserInteractionEnabled禁用时会忽略事件,不影响外观。高亮状态时文字是高亮颜色的,高亮颜色可以在故事板设置,默认是nil。
@property(nullable, nonatomic,strong) UIColor *highlightedTextColor; // default is nil
@property(nonatomic,getter=isHighlighted) BOOL highlighted; // default is NO
Baseline
基线,文本对齐的那条线。Controls the vertical alignment of the text within the label when Autoshrink is enabled. 只有启用自动缩小的时候有效。自动缩小是指label的内容变化时,字体是否自动缩小。 当内容太长要缩小字体,并且label只能显示1行的时候,才会触发。对应属性是 baselineAdjustment。三种情况,Align Baselines、Align Centers、None。
Line Breaks
运行效果和官方文档描述的不太一样:Select word wrap to place line breaks at word boundaries, or character wrap to insert line breaks in words. Truncate head, middle, and tail are usually applied for single-line labels, and describe the placement of an inserted ellipsis to represent the truncated text. Access this value at runtime with the lineBreakMode property.
@property(nonatomic) NSLineBreakMode lineBreakMode;
// 注意。以下注释是网上的说法。但是运行效果,前三个是一样的,和clipping一样。
NSLineBreakByWordWrapping = 0 //以空格为界,保留整个单词。
NSLineBreakByCharWrapping //保留整个字符
NSLineBreakByClipping //简单剪裁,到边界为止
NSLineBreakByTruncatingHead //前面部分文字以…方式省略,显示尾部文字内容
NSLineBreakByTruncatingTail //结尾部分的内容以…方式省略,显示头的文字内容。
NSLineBreakByTruncatingMiddle //中间的内容以…方式省略,显示头尾的文字内容。
最后一个是原字符串。前三个依次是 WordWrapping、CharWrapping、Clipping,效果相同。网上说苹果在缩小这三个的差距,可能要废弃了。
Autoshrink
决定在重排和裁剪文本之前,是否缩小字体。启用Tighten Letter Spacing会缩小字符间距。
//启用Autoshrink
label.adjustsFontSizeToFitWidth = YES;
//默认是0,不修改的话,会无限缩小到显示所有text
label.minimumScaleFactor = 0.5;
// 缩小字符间隔
label.allowsDefaultTighteningForTruncation = YES;
<p>
自定义 Label 的外观
使用 NSAttributedString API 来设置 attributedText,如图1所示,设置了不同颜色、字体大小、背景色。
设置了 attributedText 也可以修改其他外观属性,如图2所示,在图1的基础上设置 textColor 为绿色。
使用numberOfLines控制行数,lineBreakMode控制断行方式。
label.numberOfLines = 0; // use as many lines as necessary
label.lineBreakMode = NSLineBreakByTruncatingMiddle;
intrinsicContentSize表示label内容显示为一行的size,宽度由内容长度决定。The intrinsic content size for a label defaults to the size that displays the entirety of the content on a single line. numberOfLines设置为0也是表示一行的宽度。如果给label添加了宽度的约束,没有添加高度的约束,那么intrinsicContentSize表示显示所有内容所需的高度和宽度,而不是单行的宽度。如下图所示
当宽度不够时,可以调整字体大小和字符间隔。如图所示
label.adjustsFontSizeToFitWidth = YES; // 允许调整字体大小
label.minimumScaleFactor = 0.5; // 最小缩放倍数
label.allowsDefaultTighteningForTruncation = YES; // 缩小字符间隔
根据text计算label的高度
使用代码布局,需要根据text计算label的高度。类似QQ空间的cell,label最多显示6行,下方加个“查看全文”按钮。按钮的位置由label的高度决定,那么label的高度如何计算呢?label的宽度根据屏幕宽度计算,然后调用 textRectForBounds: limitedToNumberOfLines: 就可以获得高度了。
// 返回文字绘制区域大小。bounds限制大小,numberOfLines限制行数。子类可以重写这个方法修改文字绘制区域。
- (CGRect)textRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines;
// 根据屏幕宽度算的label宽度是100。行数要求不超过6行,高度足够显示6行就行了,给个5000吧。
int lines = 6;
float width = 100;
float height = 5000;
CGRect bounds = CGRectMake(0, 0, width, height);
// 算出的高度最多显示6行,不超过5000
CGRect frame = [label textRectForBounds:bounds limitedToNumberOfLines:lines];
// 如果设计师要求高度不超过300,行数随意,可以这样写
int lines = 0;
float height = 300;
都是计算高度,对比一下 intrinsicContentSize 和 textRectForBounds: limitedToNumberOfLines: 。前者默认计算一行的高度。前者加了宽度约束可以计算多行的高度,和后者的结果是一致的。
// 测试 加了宽度约束的 intrinsicContentSize
UILabel *label1 = [self.view viewWithTag:1];
CGSize size1 = label1.intrinsicContentSize;
NSLog(@"size = %@", NSStringFromCGSize(size1)); // 加了宽度约束,显示多行的宽高
// 测试 textRectForBounds
UILabel *label2 = [self.view viewWithTag:2];
int lines = 10;
float height = 500;
CGRect bounds = CGRectMake(0, 0, 160, height); // 160是label1的宽度
CGRect frame = [label2 textRectForBounds:bounds limitedToNumberOfLines:lines];
NSLog(@"frame = %@", NSStringFromCGRect(frame)); // 高度不大于500,行数不多于10
// 测试没有加约束的 intrinsicContentSize
CGSize size2 = label2.intrinsicContentSize;
NSLog(@"size = %@", NSStringFromCGSize(size2)); // 不加约束,显示一行的宽高
上面是label1,下面是label2。label1加了限制宽度的约束,label2不加任何约束。还有疑问请看label1的文字。
drawTextInRect:
在特定区域绘制文本。不要直接调用,可以在子类重载。重载的时候,可以进一步配置当前上下文(通过 UIGraphicsGetCurrentContext() 获取),然后调用父类的方法。如果自定义绘制,也可以不调用父类方法。
preferredMaxLayoutWidth
在viewDidLoad里面是0,viewDidLayoutSubviews里面才有值。修改这个属性,只对加了约束的控件有影响:不会改变宽度,但是会改变高度。比如加了约束宽度是160,修改这个属性为100,那么label的宽度就会增加,但是宽度不变,还是160。官方文档:This property affects the size of the label when layout constraints are applied to it. During layout, if the text extends beyond the width specified by this property, the additional text flows to one or more new lines, increasing the height of the label.
Demo
// 0、Creating a Label
CGRect frame = CGRectMake(100, 100, 100, 50);
UILabel *label = [[UILabel alloc]initWithFrame:frame];
// 1、Accessing the Text Attributes
NSAttributedString *as = [[NSAttributedString alloc]initWithString:@"as"];
label.attributedText = as;
label.text = @"text"; // attributedText和text,显示最后设置的
label.font = [UIFont systemFontOfSize:15];
label.textColor = [UIColor greenColor];
label.textAlignment = NSTextAlignmentLeft;
label.lineBreakMode = NSLineBreakByTruncatingTail;
label.enabled = YES;
// 2、Sizing the Label’s Text
label.adjustsFontSizeToFitWidth = YES;
label.minimumScaleFactor = 0.5;
label.allowsDefaultTighteningForTruncation = YES;
label.baselineAdjustment = UIBaselineAdjustmentAlignCenters; // 文字中心和label的中线重合
label.numberOfLines = 0;
// 3、Managing Highlight Values
label.highlightedTextColor = [UIColor redColor];
label.highlighted = NO;
// 4、Drawing a Shadow
label.shadowColor = [UIColor yellowColor];
label.shadowOffset = CGSizeMake(2, 2); // 往右下偏移
// 5、Drawing and Positioning Overrides
CGRect bounds = CGRectMake(0, 0, 160, 500);
CGRect rect = [label textRectForBounds:bounds limitedToNumberOfLines:0];
// drawTextInRect: // 这个不能直接调用,只能子类重载
// 6、Getting the Layout Constraints
label.preferredMaxLayoutWidth = 100;
// 7、Setting and Getting Attributes
label.userInteractionEnabled = YES;
不当之处,欢迎指正。