iOS Text Part1:TextKit

0.TextKit包含類講解

TextKit_1.png

TextKit_2.png

如圖TextKit_1可以看到,我們一般能接觸到的文字控件全是由TextKit封裝而成的孵构。

TextKit內(nèi)的三個類功能如下:
NSTextStorage:保存文字控件要顯示的NSAttributedString
NSLayoutManager:掌控文字控件對文字的具體繪制操作
NSTextContainer:把控文字控件的顯示的區(qū)域

隸屬關(guān)系如下:

 self.textStorage = [[NSTextStorage alloc] init];
 self.textLayoutManager = [[NSLayoutManager alloc] init];
 self.textContainer = [[NSTextContainer alloc]init];
    
 [self.textStorage addLayoutManager:self.textLayoutManager];
 [self.textLayoutManager addTextContainer:self.textContainer];
    
 self.textLayoutManager.delegate = self;

1.開發(fā)時的應用

TextKitTrain源碼

1.1 同一段文字分View顯示

Simulator Screen Shot 2016年7月20日 下午7.54.28.png

主角:NSTextStorage####

如圖TextKit_2可以看到办成,NSTextStorage穿肄、NSLayoutManager 和 NSTextContainer 之間的箭頭都是有兩個頭的荷科。我試圖描述它們的關(guān)系是 1 對 N 的關(guān)系阵难。就是那樣:一個 Text Storage 可以擁有多個 Layout Manager喊括,一個 Layout Manager 也可以擁有多個 Text Container炭序。這些多重性帶來了很好的特性。
很有用的一個例子徙鱼,基于頁面的布局:
頁面上有多個 Text View ,每個Text View 的 Text Container 都引用同一個 Layout Manager宅楞,一個 Text Storage持有這個 Layout Manager,這時這個 Text Storage 就可以將文本分布到多個視圖上來顯示。

1.2 文字內(nèi)不規(guī)則的區(qū)域留白

Simulator Screen Shot 2016年7月20日 下午7.54.05.png

主角:NSTextContainer####

 CGRect ovalFrame = [_textView convertRect:_panView.bounds fromView:_panView];
 // Simply set the exclusion path
 UIBezierPath * ovalPath = [UIBezierPath bezierPathWithOvalInRect:ovalFrame];
 _textView.textContainer.exclusionPaths = @[ovalPath];
 [_textView setNeedsDisplay];

拿到混入圖片的矩形坐標,由矩形坐標獲取畫圓的貝賽爾曲線,將這個貝賽爾曲線賦值給textContainer.exclusionPaths,很簡單的就在正常的顯示區(qū)域內(nèi)剪出個"洞"袱吆。

1.3 Label實現(xiàn)鏈接點擊的效果

Simulator Screen Shot 2016年7月20日 下午8.31.28.png

主角:NSLayoutManager####

before.png

select ing.png

上述為點擊高亮前后的顯示
兩副場景如果是"單獨"顯示,用attributedString+UILabel應該誰都會,難點就在兩副場景的瞬間切換,切換不同的attributedString

  • step1.預先標定高亮區(qū)域
  • step2.點擊時識別是否在高亮區(qū)域
  • step3.在高亮區(qū)域,切換Label的attributedString

1.3.1 預先標定高亮區(qū)域

UI層面預先標定:
特殊區(qū)域文字顏色與普通文字顏色不同,通過[attributedString addAttribute:NSForegroundColorAttributeName value:range:]的方式來實現(xiàn)

數(shù)據(jù)層面預先標定:
@property (nonatomic, copy) NSMutableArray * selectableRanges;
label設置selectableRanges屬性用于保存所有特殊區(qū)域的range

1.3.2 點擊時識別是否在高亮區(qū)域

 NSUInteger touchedChar = [self.textLayoutManager glyphIndexForPoint:location inTextContainer:self.textContainer];

獲取"點擊點"所點中字符的index,然后遍歷selectableRanges內(nèi)的每一個range,看是否有哪個range包含了這個index

  • 沒有一個range包含那就罷了
  • 有一個range包含就進行下一步

1.3.3 在高亮區(qū)域,切換Label的attributedString

-(void)updateShowTextWithRange:(NSRange)range color:(UIColor *)color
{
    NSMutableAttributedString * muAttr = [self.attributedText mutableCopy];
    if (range.length <= 0) {
        [muAttr removeAttribute:NSBackgroundColorAttributeName range:self.selectRange];
    }else{
        [muAttr addAttribute:NSBackgroundColorAttributeName value:color range:range];
    }
    self.attributedText = [muAttr copy];
    self.selectRange = range;
}

通過[attributedString addAttribute: NSBackgroundColorAttributeName value:range:]的方式更新點中range背景色,然后重新繪制

- (void)drawTextInRect:(CGRect)rect
{
    CGPoint textOffset;
    NSRange glyphRange = [self.textLayoutManager glyphRangeForTextContainer:self.textContainer];
    textOffset = [self calcTextOffsetForGlyphRange:glyphRange];
    //繪制背景
    [self.textLayoutManager drawBackgroundForGlyphRange:glyphRange atPoint:textOffset];
    //繪制字符
    [self.textLayoutManager drawGlyphsForGlyphRange:glyphRange atPoint:textOffset];
}

學習來源:
http://objccn.io/issue-5-1/
https://github.com/m1entus/MZSelectableLabel
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末厌衙,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子绞绒,更是在濱河造成了極大的恐慌婶希,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蓬衡,死亡現(xiàn)場離奇詭異喻杈,居然都是意外死亡拐揭,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進店門奕塑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來堂污,“玉大人,你說我怎么就攤上這事龄砰∶瞬” “怎么了?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵换棚,是天一觀的道長式镐。 經(jīng)常有香客問我,道長固蚤,這世上最難降的妖魔是什么娘汞? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮夕玩,結(jié)果婚禮上你弦,老公的妹妹穿的比我還像新娘。我一直安慰自己燎孟,他們只是感情好禽作,可當我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著揩页,像睡著了一般旷偿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上爆侣,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天萍程,我揣著相機與錄音,去河邊找鬼兔仰。 笑死茫负,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的斋陪。 我是一名探鬼主播朽褪,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼置吓,長吁一口氣:“原來是場噩夢啊……” “哼无虚!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起衍锚,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤友题,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后戴质,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體度宦,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡踢匣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了戈抄。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片离唬。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖划鸽,靈堂內(nèi)的尸體忽然破棺而出输莺,到底是詐尸還是另有隱情,我是刑警寧澤裸诽,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布嫂用,位于F島的核電站,受9級特大地震影響丈冬,放射性物質(zhì)發(fā)生泄漏嘱函。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一埂蕊、第九天 我趴在偏房一處隱蔽的房頂上張望往弓。 院中可真熱鬧,春花似錦蓄氧、人聲如沸亮航。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽缴淋。三九已至,卻和暖如春泄朴,著一層夾襖步出監(jiān)牢的瞬間重抖,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工祖灰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留钟沛,地道東北人。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓局扶,卻偏偏與公主長得像恨统,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子三妈,可洞房花燭夜當晚...
    茶點故事閱讀 45,055評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 卷首語 歡迎來到 objc.io 第五期畜埋! 我們希望你跟我們一樣為 iOS 7 的發(fā)布而感到興奮。選擇這個做為本期...
    評評分分閱讀 565評論 0 4
  • Text Kit學習(入門和進階): http://www.cocoachina.com/industry/201...
    F麥子閱讀 4,044評論 1 13
  • 以前畴蒲,如果我們想實現(xiàn)如上圖所示復雜的文本排版:顯示不同樣式的文本悠鞍、圖片和文字混排,你可能就需要借助于UIWebVi...
    Saxon_Geoffrey閱讀 14,342評論 10 72
  • 0. 基本知識準備 0.1 字形( Glyph)基本了解 基礎(chǔ)原點(Origin)首先是位于基線上處于基線最左側(cè)的...
    破弓閱讀 3,149評論 4 24
  • 學校組織春游模燥,他很興奮咖祭,六點半就起床搖醒凌晨兩點才睡的媽媽掩宜。半夢半醒的她對他說:“讓我睡到鬧鐘響,還差二十分鐘么翰。你...
    細嗅野薔薇閱讀 258評論 6 2