偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

在iOS中如何正確的實(shí)現(xiàn)行間距與行高

移動(dòng)開(kāi)發(fā) iOS
面向 Google 以及 Stack Overflow 編程了一會(huì)后發(fā)現(xiàn),能查到的資料大部分是介紹如何實(shí)現(xiàn) lineSpacing 屬性,而不是 lineHeight。但是我就是因?yàn)?iOS 和 Android 的默認(rèn) lineSpacing 不一致所以才想實(shí)現(xiàn)個(gè) lineHeight 啊!

最近準(zhǔn)備給 VirtualView-iOS 的文本元素新增一個(gè) lineHeight 屬性,以便和 VirtualView-Android 配合時(shí)能更精確的保證雙平臺(tái)的一致性。面向 Google 以及 Stack Overflow 編程了一會(huì)后發(fā)現(xiàn),能查到的資料大部分是介紹如何實(shí)現(xiàn) lineSpacing 屬性,而不是 lineHeight。但是我就是因?yàn)?iOS 和 Android 的默認(rèn) lineSpacing 不一致所以才想實(shí)現(xiàn)個(gè) lineHeight 啊!還是需要自己動(dòng)手豐衣足食,順帶整理成文章造福后人。

關(guān)于行間距 lineSpacing

先貼出一張 iOS 中 UILabel 的默認(rèn)排版樣式:

 

26-A

大家也都能看出來(lái),默認(rèn)的排版樣式中,文本的行間距很小,顯得文本十分?jǐn)D。

這種時(shí)候,設(shè)計(jì)師就會(huì)提出行間距的需求,希望讓文本展示得更美觀。類(lèi)似的標(biāo)注就會(huì)像這樣:

 

26-B

通常來(lái)說(shuō)既然設(shè)計(jì)師要求的是行間距,那么我們直接設(shè)置 lineSpacing 就好。但是 UILabel 是沒(méi)有這么一個(gè)直接暴露的屬性的,想要修改 lineSpacing,我們需要借助 NSAttributedString 來(lái)實(shí)現(xiàn),示意代碼:

 

  1. NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new]; 
  2. paragraphStyle.lineSpacing = 10; 
  3. NSMutableDictionary *attributes = [NSMutableDictionary dictionary]; 
  4. [attributes setObject:paragraphStyle forKey:NSParagraphStyleAttributeName]; 
  5. label.attributedText = [[NSAttributedString alloc] initWithString:label.text attributes:attributes]; 

運(yùn)行一下觀察效果:

 

26-C

雖然用我們的眼睛看上去好像沒(méi)什么問(wèn)題,但是設(shè)計(jì)師的火眼金睛一下就能看出來(lái),和設(shè)計(jì)稿要求的有差距:

 

26-D

怎么會(huì)成這樣!?這跟說(shuō)好的不一樣對(duì)不對(duì)!?不要慌,我來(lái)細(xì)細(xì)解釋下。

正確的實(shí)現(xiàn)行間距

先看示意圖:

 

26-E

紅色區(qū)域是默認(rèn)繪制單行文本會(huì)占用的區(qū)域,可以看到文字的上下是有一些留白的(藍(lán)色和紅色重疊的部分)。設(shè)計(jì)師是想要藍(lán)色區(qū)域高度為 10pt,而我們直接設(shè)置 lineSpacing 會(huì)將兩行紅色區(qū)域中間的綠色區(qū)域高度設(shè)置為 10pt,這就是問(wèn)題的根源了。

那么這個(gè)紅色的區(qū)域高度是多少呢?答案是 label.font.lineHeight,它是使用指定字體繪制單行文本的原始行高。

知道了原因后問(wèn)題就好解決了,我們需要在設(shè)置 lineSpacing 時(shí),減去這個(gè)系統(tǒng)的自帶邊距:

 

  1. NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new]; 
  2. paragraphStyle.lineSpacing = 10 - (label.font.lineHeight - label.font.pointSize); 
  3. NSMutableDictionary *attributes = [NSMutableDictionary dictionary]; 
  4. [attributes setObject:paragraphStyle forKey:NSParagraphStyleAttributeName]; 
  5. label.attributedText = [[NSAttributedString alloc] initWithString:label.text attributes:attributes]; 

觀察一下效果,***契合:

 

26-F

關(guān)于行高 lineHeight

如果你只關(guān)心 iOS 設(shè)備上的文本展示效果,那么看到這里就已經(jīng)夠了。但是我需要的是 iOS 和 Android 展現(xiàn)出一模一樣的效果,所以光有行間距是不能滿(mǎn)足需求的。主要的原因在前言也提到了,Android 設(shè)備上的文字上下默認(rèn)留白(上一節(jié)圖中藍(lán)色和紅色重疊的部分)和 iOS 設(shè)備上的是不一致的:

 

26-G

左側(cè)是 iOS 設(shè)備,右側(cè) Android 設(shè)備,可以看到同樣是顯示 20 號(hào)的字體,安卓的行高會(huì)偏高一些。在不同的 Android 設(shè)備上使用的字體不一樣,可能還會(huì)出現(xiàn)更多的差別。如果不想辦法抹平這差別,就不能真正意義上實(shí)現(xiàn)雙端一致了。

這時(shí)候我們可以通過(guò)設(shè)置 lineHeight 來(lái)使得每一行文本的高度一致,lineHeight 設(shè)置為 30pt 的情況下,一行文本高度一定是 30pt,兩行文本高度一定是 60pt。雖然文字的渲染上會(huì)有細(xì)微的差別,但是布局上的差別將被完全的抹除。lineHeight 同樣可以借助 NSAttributedString 來(lái)實(shí)現(xiàn),示意代碼:

 

  1. NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new]; 
  2. paragraphStyle.maximumLineHeight = lineHeight; 
  3. paragraphStyle.minimumLineHeight = lineHeight; 
  4. NSMutableDictionary *attributes = [NSMutableDictionary dictionary]; 
  5. [attributes setObject:paragraphStyle forKey:NSParagraphStyleAttributeName]; 
  6. label.attributedText = [[NSAttributedString alloc] initWithString:label.text attributes:attributes]; 

運(yùn)行一下觀察效果:

 

27-A

在 debug 模式下確認(rèn)了下文本的高度的確正確的,但是為什么文字都顯示在了行底呢?

修正行高增加后文字的位置

修正文字在行中展示的位置,我們可以用 baselineOffset 屬性來(lái)搞定。這個(gè)屬性十分有用,在實(shí)現(xiàn)上標(biāo)下標(biāo)之類(lèi)的需求時(shí)也經(jīng)常用到它。經(jīng)過(guò)調(diào)試,發(fā)現(xiàn)最合適的值是 (lineHeight - label.font.lineHeight) / 4(尚未搞清楚為什么是除以 4 而不是除以 2,希望知道的老司機(jī)指點(diǎn)一二)。最終的代碼示例如下:

 

  1. NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new]; 
  2. paragraphStyle.maximumLineHeight = lineHeight; 
  3. paragraphStyle.minimumLineHeight = lineHeight; 
  4. NSMutableDictionary *attributes = [NSMutableDictionary dictionary]; 
  5. [attributes setObject:paragraphStyle forKey:NSParagraphStyleAttributeName]; 
  6. CGFloat baselineOffset = (lineHeight - label.font.lineHeight) / 4; 
  7. [attributes setObject:@(baselineOffset) forKey:NSBaselineOffsetAttributeName]; 
  8. label.attributedText = [[NSAttributedString alloc] initWithString:label.text attributes:attributes]; 

貼一下在不同字號(hào)和行高下的展示效果:

 

27-B

行高和行間距同時(shí)使用時(shí)的一個(gè)問(wèn)題

不得不說(shuō)行高和行間距我們都已經(jīng)可以***的實(shí)現(xiàn)了,但是我在嘗試同時(shí)使用它們時(shí),發(fā)現(xiàn)了 iOS 的一個(gè) bug(當(dāng)然也可能是一個(gè) feature,畢竟不 crash 都不一定是 bug):

 

27-C

著色的區(qū)域都是文本的繪制區(qū)域,其中看上去是橙色的區(qū)域是 lineSpacing,綠色的區(qū)域是 lineHeight。但是為什么單行的文本系統(tǒng)也要展示一個(gè) lineSpacing 啊!?坑爹呢這是!?

好在我們通常是行高和行間距針對(duì)不同的需求分別獨(dú)立使用的,它們?cè)诜珠_(kāi)使用時(shí)不會(huì)觸發(fā)這個(gè)問(wèn)題。所以在 VirtualView-iOS 庫(kù)中,我暫且將高度計(jì)算的邏輯保持和系統(tǒng)一致了。

總結(jié)

至此,成功的為 VirtualView-iOS 添加了對(duì) lineHeight 屬性的支持,更多的實(shí)現(xiàn)細(xì)節(jié)大家可以到開(kāi)源庫(kù)中直接看源代碼。希望我們的 Tangram 方案可以更加完善,幫助更多的人一次開(kāi)發(fā)兩端同時(shí)使用,用一塊七巧板拼出大千世界。

責(zé)任編輯:未麗燕 來(lái)源: 蘋(píng)果核
相關(guān)推薦

2015-07-22 12:42:36

Pivot行列轉(zhuǎn)換

2021-08-26 08:24:33

高并發(fā)秒殺系統(tǒng)

2010-04-26 10:09:22

Oracle存儲(chǔ)過(guò)程

2024-11-28 09:59:35

2009-12-07 18:42:55

PHP與Javascr

2024-09-19 20:59:49

2010-06-28 12:46:09

SQL Server

2018-11-01 17:06:06

cell自適應(yīng)高主

2015-07-14 11:07:43

IOS一像素線

2009-12-03 20:09:03

Tomcat支持PHP

2010-03-04 15:24:14

Python程序

2024-01-29 00:57:20

GuavaJava拷貝

2010-04-29 17:31:56

Oracle存儲(chǔ)過(guò)程

2009-09-15 18:27:59

equals實(shí)現(xiàn)canEqualScala

2014-04-09 09:32:24

Go并發(fā)

2010-05-05 17:19:32

Oracle存儲(chǔ)過(guò)程

2019-08-19 08:14:52

深度鏈接iOSAndroid

2010-09-01 15:30:24

SQL刪除

2024-12-27 09:32:19

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)