一、开发问题
开发中,按照设计稿去做的页面,为何总是无法与设计稿完美对应?怎样才能精准的还原设计稿样式?
相信大家都遇到过类似问题,今天来探讨下如何通过对齐的方式尽可能精准的还原文本的展示样式。
二、文本的属性
文本对图中做几点解释:
- baseline:相当于坐标原点,默认设定中大部分的拉丁字母底部与此对齐,汉字的中下部与此对齐。
- ascent:字体可绘制区域的上部最大值,ascent在大部分情况下会比最高的字符还要高一点点,可能是系统设定。
- descent:与ascent相似,是字体可绘制区域的下部最大值,可能为负值。
- leading:行间距,与传统意义的行间距并不相同,不同的字体在显示时视觉上的行间距不同,这时说的是这个值。
- line height:行高,= ascent + |descent| + leading。
需要注意,以上属性为字体本身的属性,应该是字体设计时就定好的,理论上是不可变的(富文本中对应
baselineOffset
改变的是富文本显示的对齐方式)
另外,iOS中的字体大小,即
UIFont
的pointSize
属性,并不直接对应行高,一般一个字体是10的文本,line height一般为11.89,大约为字体大小的1.2倍,所以按照这个结果来看,iOS字体默认是1.2倍行高。
三、行间距和行高
行高及行间距继续先来对图中做几点解释:
- line space:行间距,直接对应两行文本之间的间距值。
- line height of font:每一行文字的高度。
- 行高:每一行的实际高度,= line height of font + line space。
-
行高倍数:
lineHeightMultiple
,几倍行高,= 行高 / line height。
四、NSAttributeString的对应属性
在iOS开发中使用富文本进行行设置时主要通过段落类型
NSMutableParagraphStyle
来进行设置,对应富文本中的NSAttributedStringKey.paragraphStyle
主要涉及属性如下:
-
lineSpacing
:行间距,会在每行位子之间添加间距,在首行的顶部与尾行的底部没有额外的空白。比较符合我们大多数的需求,但不太适合和通用型设置,因为不同的字体大小为实现相同效果可能需要设置不同的行间距,比较繁琐。 -
minimumLineHeight/maximumLineHeight/lineHeightMultiple
:最小行高/最大行高/行高倍数,这几个属性都是直接设置行高的,存在的问题是如果行高大于文字的高度(line height of font),那么多余的空间会放在该行的上方,即baseline
所在的位置是该行的最底部向上偏移leading + |descent|
的位置。可搭配使用富文本的baselineOffset
属性来设置对齐,但总体不是很方便。
根据上面提到的一些缺点,开发中可以考虑组合使用,例如要求行高为a px
,字体大小为b px
,则:
- 因为系统中默认为1.2倍行距,所以文字行高为:
line_height_of_font = b * 1.2
。 - 文字在行中居中显示,所以每行中文字与该行顶部的间距:
line_top = (a - line_height_of_font) / 2
。 - 所以每行行高设置为:
minimumLineHeight = line_height_of_font + line_top = (a - b * 1.2) / 2 + b * 1.2
。 - 此时设置两行之间的间距为:
lineSpacing = a - minimumLineHeight
。 - 最后在计算该富文本行高时,底部加上一个
lineSpacing
,实现最后一行与底部的间距。
网友评论