潮州哪里好玩如何正确的使⽤NSAttributedString在iOS中实现⾏间距与⾏⾼
最近准备给 VirtualView-iOS 的⽂本元素新增⼀个 lineHeight 属性,以便和 VirtualView-Android 配合时能更精确的保证双平台的⼀致性。⾯向 Google 以及 Stack Overflow 编程了⼀会后发现,能查到的资料⼤部分是介绍如何实现 lineSpacing 属性,⽽不是 lineHeight。但是我就是因为 iOS 和 Android 的默认 lineSpacing 不⼀致所以才想实现个 lineHeight 啊!还是需要⾃⼰动⼿丰⾐⾜⾷,顺带整理成⽂章造福后⼈。
幼儿园学期计划
关于⾏间距 lineSpacing
先贴出⼀张 iOS 中 UILabel 的默认排版样式:
26-A
⼤家也都能看出来,默认的排版样式中,⽂本的⾏间距很⼩,显得⽂本⼗分挤。
发声训练方法碧海青天夜夜心是什么意思这种时候,设计师就会提出⾏间距的需求,希望让⽂本展⽰得更美观。类似的标注就会像这样:
26-B中枢机构
通常来说既然设计师要求的是⾏间距,那么我们直接设置 lineSpacing 就好。但是 UILabel 是没有这么⼀个直接暴露的属性的,想要修改lineSpacing,我们需要借助 NSAttributedString 来实现,⽰意代码:
运⾏⼀下观察效果:
26-C
虽然⽤我们的眼睛看上去好像没什么问题,但是设计师的⽕眼⾦睛⼀下就能看出来,和设计稿要求的有差距:
26-D
怎么会成这样!?这跟说好的不⼀样对不对!?不要慌,我来细细解释下。
正确的实现⾏间距
先看⽰意图:
26-E
牙医的英语红⾊区域是默认绘制单⾏⽂本会占⽤的区域,可以看到⽂字的上下是有⼀些留⽩的(蓝⾊和红⾊重叠的部分)。设计师是想要蓝⾊区域⾼度为
10pt,⽽我们直接设置 lineSpacing 会将两⾏红⾊区域中间的绿⾊区域⾼度设置为 10pt,这就是问题的根源了。
连忙造句那么这个红⾊的区域⾼度是多少呢?答案是 label.font.lineHeight,它是使⽤指定字体绘制单⾏⽂本的原始⾏⾼。
知道了原因后问题就好解决了,我们需要在设置 lineSpacing 时,减去这个系统的⾃带边距:
观察⼀下效果,完美契合:
26-F
关于⾏⾼ lineHeight
如果你只关⼼ iOS 设备上的⽂本展⽰效果,那么看到这⾥就已经够了。但是我需要的是 iOS 和 Android 展现出⼀模⼀样的效果,所以光有⾏间距是不能满⾜需求的。主要的原因在前⾔也提到了,Android 设备上的⽂字上下默认留⽩(上⼀节图中蓝⾊和红⾊重叠的部分)和 iOS 设备上的是不⼀致的:
26-G
左侧是 iOS 设备,右侧 Android 设备,可以看到同样是显⽰ 20 号的字体,安卓的⾏⾼会偏⾼⼀些。在不同的 Android 设备上使⽤的字体不⼀样,可能还会出现更多的差别。如果不想办法抹平这差别,就不能真正意义上实现双端⼀致了。
这时候我们可以通过设置 lineHeight 来使得每⼀⾏⽂本的⾼度⼀致,lineHeight 设置为 30pt 的情况下,⼀⾏⽂本⾼度⼀定是 30pt,两⾏⽂本⾼度⼀定是 60pt。虽然⽂字的渲染上会有细微的差别,但是布局上的差别将被完全的抹除。lineHeight 同样可以借助 NSAttributedString 来实现,⽰意代码:
运⾏⼀下观察效果:
27-A
在 debug 模式下确认了下⽂本的⾼度的确正确的,但是为什么⽂字都显⽰在了⾏底呢?
修正⾏⾼增加后⽂字的位置
修正⽂字在⾏中展⽰的位置,我们可以⽤ balineOfft 属性来搞定。这个属性⼗分有⽤,在实现上标下标之类的需求时也经常⽤到它。经过调试,发现最合适的值是 (lineHeight - label.font.lineHeight) / 4(尚未搞清楚为什么是除以 4 ⽽不是除以 2,希望知道的⽼司机指点⼀⼆)。最终的代码⽰例如下:
贴⼀下在不同字号和⾏⾼下的展⽰效果:
27-B
⾏⾼和⾏间距同时使⽤时的⼀个问题
不得不说⾏⾼和⾏间距我们都已经可以完美的实现了,但是我在尝试同时使⽤它们时,发现了 iOS 的⼀个 bug(当然也可能是⼀个 feature,毕
美国的国花是什么