tablewidget字体显示不全_ios 容器内容显示原理及调整

先发一行文字,看一下奇特之处:

09afgjkpqz汉字

ccf079c67b4584a7ec20868ff45128a5.png


这是编辑器自动加的横线

iOS,OS文本容器中都是基线对齐,所谓的基线对齐就是指无论中文字符,数字,英文字符,表情等它们在一行的时候,基线是在同一高度的。图例中的红线就是基线。

9e3d67bc1c6d2f628cc7de3ccad27133.png


1

1669b8677b06f3a54f48ab2db39c80b1.png


2

概念:

baseline: 相当于坐标原点。大部分的拉丁字母底部与此对齐,汉字的中下部与此对齐(这是设定)

ascent, descent: 相当于字体可绘制区域的上下最大值。根据自己的观察,ascent 并不一定是最高字符的高度(比如上图的 f),在大部分字体中,ascent 会比最高的字符还要高一些,上面会有个空间。 desecnt 同理。(descent 为负值)

leading: 即行间距。但这个行间距与平时所说的行间距并不是一个东西。在文本编辑器中,选择不同字体的时候,视觉上的每行的距离并不是一样的。有可能就是 leading 不同。这个值可能为 0。(对于 iOS 上的 SF 系列字体,它的值就是 0 )

line height: 即行高。它的值定义为 ascent + descent + leading。(descent 为负值,所以准确的写应该取绝对值)。这也是我们最关心的一个值。

这些值都是字体的属性,是字体的设计者制定的,不可变,不同的字体会不一样。

平时用来表示字体大小的「字号」并不对应上图中的任何值,也就没有一个直接的几何意义。字号准确的说法是 point size。对于一个 point size 是 15 的 SFUI 字体,它的 line height 为 17.900390625, 约为 point size 的 1.2 倍。所以对于这个字体的一行文字,它的行高为 17.900390625。如果硬要显示在 15.0 高度的矩形内,g 和 f 应该会显示不全。

行间距

line height 所代表的高度只是一行文字的高度。可以把一行文字看做以 line height 为高的矩形,多行文字就是这些矩形纵向排列。矩形的间距就是通常我们说的行间距:

04841566ece5fba3d6c2ae93917af4fb.png

而通常所说的「行间距」「行高」「line height mutiple」 这样的词语,描述的就是这个间距的大小。

「行间距」: 直接对应间距的值

「行高」: line height + 间距。可以认为是,除了首行与尾行,每行实际所占的高度

line height mutiple: 即是「 x 倍行高」中的数值。line_height_mutiple = 「行高」/ line_height

不同平台的实现效果

iOS

使用 autolayout 的一行 UIlabel 的高度即为所使用字体的 line height。但 autolayout 中,view 的 frame 的小数点精度会对齐到像素精度。所以 15 号字体的 label 高度为 18.0 point 。

对于多行文字的行间距,可以通过 attributedString 中的 paragraph style 来控制。paragraph style 可以设定如下值:

lineHeightMultiple: 同上面所说的。

minimumLineHeight/maximumLineHeight: 即「行高」

这两个值都会改变行高,只是写法不同而已。但使用它们控制行间距有一个问题,如果行高大于字体的 line height,那么多余的空间将会放在这行的上面: baseline 所在的位置是矩形底边 + ( leading + descent ) 的位置。一个常见的情况,圆形的 avatar 与右侧的 label 顶端对齐,如果使用 lineHeightMultiple,那么为了达到视觉上的对齐,avatar 与 label 的 frame.y 就会不一样。不是很理想。(在使用 insets 或 background color 的时候就会很麻烦)

lineSpacing: 即行间距。

使用 lineSpacing 只会在每行之间添加间距。在首行与尾行外侧并没有额外的空白(当然,line height 里所带的空白仍然存在)。比较符合我们行间距的设定,不存在上面提到的问题。但不同 point size 为了有同样的效果,需要设定不同的 lineSpacing,不如 lineHeightMultiple 使用方便。

实际使用:

22a41c3e0ef2e6e2746a802d6b514e31.png


4

假设UI提供了这样一种效果,让开发来实现。

8b1eedb87f13c61f172edcb418d8599a.png


5

你开发完之后发现是这样的。

这时候就需要设置富文本的NSBaselineOffsetAttributeName来实现不同字号的文字的垂直居中对齐了。

NSBaselineOffsetAttributeName:@(0.36*(a-b)),a是本行文本最大字号,b是当前文本段的字号。设置为就可以实现4的效果了。至于为什么用0.36这个神奇数字,暂时未知 ̄□ ̄||

88661aff758454c5b4fd53e233b4a0ce.png


6

对于图6的难以理解的UI设计,实现亦可以通过设置NSBaselineOffsetAttributeName来实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值