CoreText是專門進行文字繪製的函數集合數組
CoreText 將單個字符分爲函數
· baseline(基線),一條假想的線,一行上的字形都以此線做爲上下位置的參考,在這條線的左側存在一個點叫作基線的原點,
· ascent(上行高度)從原點到字體中最高(這裏的高深都是以基線爲參照線的)的字形的頂部的距離,ascent是一個正值
· descent(下行高度)從原點到字體中最深的字形底部的距離,descent是一個負值(好比一個字體原點到最深的字形的底部的距離爲2,那麼descent就爲-2)
· linegap(行距),linegap也能夠稱做leading(其實準確點講應該叫作External leading),行高lineHeight則能夠經過 ascent + |descent| + linegap 來計算。字體
使用CoreText繪製一段文字的步驟爲:spa
1.獲取畫布 CGContextReform
2.設置座標系。由於CoreText的座標系是左下角,可是UIView的座標系是左上角,須要進行相應翻轉,才方便進行操做。對象
CGContextSetTextMatrix(context,CGAffineTransformIdentity);//設置字形變換矩陣,當前值表示不作任何字形變換處理索引
CGContextTranslateCTM(context, 0, self.frame.size.height);//將繪製原點從左下角位移到左上角it
CGContextScaleCTM(context, 1, -1);//將座標翻轉180度io
3.設置須要繪製的文本 NSMutableAttributedStringtable
4.使用CTFramesetterCreateWithAttributedString 從NSMutableAttributedString中生成 CTFramesetterRef
5.設置CTFrameRef的繪製區域
CGMutablePathRef path=CGPathCreateMutable();
CGPathAddRect(path, NULL, CGRectMake(20, 20, self.frame.size.width-40, self.frame.size.height-40));
6.從CTFramesetterRef中生成 CTFrameRef 。
CTFramesetterCreateFrame(ctframesetter, CFRangeMake(0, attrstr.length), path, NULL);
7.繪製CTFrameRef
CTFrameDraw(ctframe, context);
除了直接繪製CTFrameRef以外還能夠對每一行進行單獨處理,步驟爲:
其餘步驟跟上面前6步驟徹底同樣
7.獲取CTFrameRef中的全部行
CFArrayRef array=CTFrameGetLines(ctframe); //獲取全部的行的數組
NSInteger arrcount=CFArrayGetCount(array);//獲取數組的長度
8.循環這個行數組獲取行對象
CTLineRef line=CFArrayGetValueAtIndex(array, i);//獲取第i行
9.可使用 CTLineCreateJustifiedLine 函數對行進行處理,將全部不滿一行的進行拉伸到滿一行的位置
CTLineRef justifiedLine = CTLineCreateJustifiedLine(line, 1.0f, self.frame.size.width-40);
CFRelease(line);
line = justifiedLine;
10.能夠動態調整行的位置
float asent;//行的上半部分高度
float descent;//行的下半部分高度
float leading;//行間距
CTLineGetTypographicBounds(line, &asent, &descent, &leading);//獲取行的一些屬性
CGContextSetTextPosition(context,myline.point.x,self.frame.size.height-(asent+descent+leading)*(i+1)-20);//設置行的文字位置,行的座標位置設置仍然以左下角爲原點的
11.將行文字繪製在界面上
CTLineDraw(line, context);
這裏面有一些函數須要特殊注意,可能比較有用途
1.這個函數用來處理行寬不一致的問題,有些行的因爲內部有一些標點符號,沒法佔滿整行,致使行寬良莠不齊,這個函數專門處理這個問題。
CTLineRef __nullable CTLineCreateJustifiedLine(
CTLineRef line,
CGFloat justificationFactor,
double justificationWidth ) CT_AVAILABLE(10_5, 3_2);
2. 獲取行中間某一個索引位置的字符的x座標
其中 charIndex參數的索引是整段文字的文字位置索引
CGFloat CTLineGetOffsetForStringIndex(
CTLineRef line,
CFIndex charIndex,
CGFloat * __nullable secondaryOffset ) CT_AVAILABLE(10_5, 3_2);
3.根據一個點的座標位置獲取在這個行中字符位置的索引
CFIndex CTLineGetStringIndexForPosition(
CTLineRef line,
CGPoint position ) CT_AVAILABLE(10_5, 3_2);
4.獲取行的一些信息,其中返回值爲行的總體寬度,行的高度爲ascent+descent
double CTLineGetTypographicBounds(
CTLineRef line,
CGFloat * __nullable ascent,
CGFloat * __nullable descent,
CGFloat * __nullable leading ) CT_AVAILABLE(10_5, 3_2);