1.iOS中的round辜窑、ceil、floor函數(shù)略解
round如果參數(shù)是小數(shù)寨躁,則求本身的四舍五入.ceil如果參數(shù)是小數(shù)穆碎,則求最小的整數(shù)但不小于本身.floor如果參數(shù)是小數(shù),則求最大的整數(shù)但不大于本身.
Example:如何值是3.4的話职恳,則
-- round 3.000000
-- ceil 4.000000
-- floor 3.00000
【CSDN技術(shù)主題月】深度學(xué)習(xí)框架的重構(gòu)與思考深度學(xué)習(xí)代碼專欄攢課--我的學(xué)習(xí)我做主知識庫個人圖譜上線所禀,快來領(lǐng)取~
關(guān)閉
2016-09-08 18:14241人閱讀評論(0)收藏舉報(bào)
分類:
iOS連載(8)
版權(quán)聲明:本文為博主原創(chuàng)文章方面,未經(jīng)博主允許不得轉(zhuǎn)載。
排版過程中一個重要的步驟就是從字符到字形的轉(zhuǎn)換恭金,字符表示信息本身,而字形是它的圖形表現(xiàn)形式褂策。字符一般就是指某種編碼横腿,如Unicode編碼,而字形則是這些編碼對應(yīng)的圖片斤寂。但是他們之間不是一一對應(yīng)關(guān)系耿焊,同個字符的不同字體族,不同字體大小扬蕊,不同字體樣式都對應(yīng)了不同的字形艇拍。而由于連寫(Ligatures)的存在桑包,多個字符也會存在對應(yīng)一個字形的情況姚垃。
下面就來詳情看看字形的各個參數(shù)也就是所謂的字形度量Glyph Metrics
(1)函筋、邊界框 bbox(bounding box)
這是一個假想的框子,它盡可能緊密的裝入字形再愈。
(2)榜苫、基線(baseline)
一條假想的線,一行上的字形都以此線作為上下位置的參考,在這條線的左側(cè)存在一個點(diǎn)叫做基線的原點(diǎn)翎冲,
(3)垂睬、上行高度(ascent)
從原點(diǎn)到字體中最高(這里的高深都是以基線為參照線的)的字形的頂部的距離,ascent是一個正值
(4)抗悍、下行高度(descent)
從原點(diǎn)到字體中最深的字形底部的距離驹饺,descent是一個負(fù)值(比如一個字體原點(diǎn)到最深的字形的底部的距離為2,那么descent就為-2)
(5)缴渊、行距(line gap)
line gap也可以稱作leading(其實(shí)準(zhǔn)確點(diǎn)講應(yīng)該叫做External leading),行高line Height則可以通過 ascent + |descent| + linegap 來計(jì)算赏壹。
(6)、字間距(Kerning)
字與字之間的距離衔沼,為了排版的美觀蝌借,并不是所有的字形之間的距離都是一致的,但是這個基本步影響到我們的文字排版指蚁。
(7)菩佑、基礎(chǔ)原點(diǎn)(Origin)
基線上最左側(cè)的點(diǎn)。
紅框高度既為當(dāng)前行的行高凝化,綠線為baseline稍坯,綠色到紅框上部分為當(dāng)前行的最大Ascent,綠線到黃線為當(dāng)前行的最大Desent搓劫,而黃框的高即為行間距劣光。由此可以得出:lineHeight = Ascent + |Decent| + Leading袜蚕。
傳統(tǒng)的Mac中的坐標(biāo)系的原點(diǎn)在左下角绢涡,比如NSView默認(rèn)的坐標(biāo)系,原點(diǎn)就在左下角遣疯。但Mac中有些View為了其實(shí)現(xiàn)的便捷將原點(diǎn)變換到左上角雄可,像NSTableView的坐標(biāo)系坐標(biāo)原點(diǎn)就在左上角。
iOSUIKit中缠犀,UIView是以左上角為原點(diǎn)数苫,而Core Text一開始的定位是使用與桌面應(yīng)用的排版系統(tǒng),桌面應(yīng)用的坐標(biāo)系是以左下角為原點(diǎn)辨液,即Core Text在繪制的時(shí)候也是參照左下角為原點(diǎn)進(jìn)行繪制的虐急,所以需要對當(dāng)前的坐標(biāo)系進(jìn)行處理。
實(shí)際上滔迈,Core Graphic 中的context也是以左下角為原點(diǎn)的止吁, 但是為什么我們用Core Graphic
繪制一些簡單的圖形的時(shí)候不需要對坐標(biāo)系進(jìn)行處理呢,是因?yàn)橥ㄟ^這個方法UIGraphicsGetCurrentContext()來獲得的當(dāng)前context是已經(jīng)被處理過的了燎悍,用下面方法可以查看指定的上下文的當(dāng)前圖形狀態(tài)變換矩陣敬惦。
方法一
//因?yàn)镃ore Text要配合Core Graphic 配合使用的,如Core Graphic一樣谈山,繪圖的時(shí)候需要獲得當(dāng)前的上下文進(jìn)行繪制CGContextRef context = UIGraphicsGetCurrentContext();NSLog(@"當(dāng)前context的變換矩陣 %@", NSStringFromCGAffineTransform(CGContextGetCTM(context)));//翻轉(zhuǎn)當(dāng)前的坐標(biāo)系(因?yàn)閷τ诘讓永L制引擎來說俄删,屏幕左下角為(0,0))CGContextSetTextMatrix(context, CGAffineTransformIdentity);//設(shè)置字形變換矩陣為CGAffineTransformIdentity奏路,也就是說每一個字形都不做圖形變換CGAffineTransform flipVertical = CGAffineTransformMake(1,0,0,-1,0,self.bounds.size.height);CGContextConcatCTM(context, flipVertical);//將當(dāng)前context的坐標(biāo)系進(jìn)行flipNSLog(@"翻轉(zhuǎn)后context的變換矩陣 %@", NSStringFromCGAffineTransform(CGContextGetCTM(context)));
1
2
3
4
5
6
7
8
1
2
3
4
5
6
7
8
打印結(jié)果為:
當(dāng)前context的變換矩陣[2, 0, 0, -2, 0, 800]翻轉(zhuǎn)后context的變換矩陣[2, 0, 0, 2, 0, 0]
1
2
1
2
方法二
//因?yàn)镃ore Text要配合Core Graphic 配合使用的畴椰,如Core Graphic一樣,繪圖的時(shí)候需要獲得當(dāng)前的上下文進(jìn)行繪制CGContextRefcontext= UIGraphicsGetCurrentContext();NSLog(@"當(dāng)前context的變換矩陣 %@", NSStringFromCGAffineTransform(CGContextGetCTM(context)));//翻轉(zhuǎn)當(dāng)前的坐標(biāo)系(因?yàn)閷τ诘讓永L制引擎來說鸽粉,屏幕左下角為(0斜脂,0))CGContextSetTextMatrix(context, CGAffineTransformIdentity);CGContextTranslateCTM(context,0, self.bounds.size.height);CGContextScaleCTM(context,1.0, -1.0);NSLog(@"翻轉(zhuǎn)后context的變換矩陣 %@", NSStringFromCGAffineTransform(CGContextGetCTM(context)));
1
2
3
4
5
6
7
8
1
2
3
4
5
6
7
8
打印:
當(dāng)前context的變換矩陣[2, 0, 0, -2, 0, 800]翻轉(zhuǎn)后context的變換矩陣[2, 0, -0, 2, 0, 0]
1
2
1
2
可以發(fā)現(xiàn)變換矩陣與CGAffineTransformIdentity的值[1, 0, 0, 1, 0,
0]是不相同的潜叛,并且與設(shè)備是否為Retina屏和設(shè)備尺寸相關(guān)秽褒。他的作用是將上下文空間坐標(biāo)系進(jìn)行翻轉(zhuǎn),并使原來的左下角原點(diǎn)變成左上角是原點(diǎn)威兜,并將向上為正y軸變?yōu)橄蛳聻檎齳軸销斟。
所以在使用drawRect的時(shí)候,當(dāng)前的context已經(jīng)被做了一次翻轉(zhuǎn)椒舵,如果不對當(dāng)前的坐標(biāo)系進(jìn)行處理蚂踊,會發(fā)現(xiàn),繪制出來的文字是鏡像上下顛倒的笔宿。所以在UIView的drawRect方法中的context上進(jìn)行Core
Text繪制之前需要對context進(jìn)行一次Flip犁钟。
1、傳入CTFrame涝动,返回一個裝有多個CTLine對象的數(shù)組迈勋。
CFArrayRefCTFrameGetLines(
CTFrameRef frame )CT_AVAILABLE(10_5,3_2);
1
2
1
2
2、獲取數(shù)組中的元素個數(shù)
CFIndexCFArrayGetCount(CFArrayRef theArray);
1
1
3醋粟、獲取數(shù)組中第idx個元素
constvoid*CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx);
1
1
4靡菇、 獲取所有CTLineRef的基礎(chǔ)原點(diǎn),傳入CTFrame米愿,CFRange厦凤,和一個CGPoint的結(jié)構(gòu)體數(shù)組指針,該函數(shù)會把每一個CTLine的origin坐標(biāo)寫到數(shù)組里育苟。
voidCTFrameGetLineOrigins(? ? ? ? CTFrameRef frame,? ? ? ? CFRange range,CGPointorigins[] ) CT_AVAILABLE(10_5,3_2);
1
2
3
4
1
2
3
4
5较鼓、獲取CTLine中文字在整段文字中的Range
CFRangeCTLineGetStringRange(
CTLineRef line )CT_AVAILABLE(10_5,3_2);
1
2
1
2
6、獲取CTLine中的CTRun的數(shù)組
CFArrayRefCTLineGetGlyphRuns(
CTLineRef line )CT_AVAILABLE(10_5,3_2);
1
2
1
2
7违柏、獲取CTRun在整段文字中的Range
CFRangeCTRunGetStringRange(
CTRunRef run )CT_AVAILABLE(10_5,3_2);
1
2
1
2
8博烂、 獲取點(diǎn)擊處position文字在整段文字中的index
CFIndexCTLineGetStringIndexForPosition(
CTLineRef line,
CGPoint position )CT_AVAILABLE(10_5,3_2);
1
2
3
1
2
3
9、獲取整段文字中charIndex位置的字符相對line的原點(diǎn)的x值
CGFloatCTLineGetOffsetForStringIndex(? ? CTLineRef line,? ? CFIndex charIndex,CGFloat* __nullable secondaryOffset ) CT_AVAILABLE(10_5,3_2);
1
2
3
4
1
2
3
4
10勇垛、獲取數(shù)組中字形個個數(shù)
CFIndexCTLineGetGlyphCount(
CTLineRef line )CT_AVAILABLE(10_5,3_2);
1
2
1
2
11脖母、設(shè)置CoreText繪制前的坐標(biāo)。設(shè)置基線位置
CG_EXTERNvoidCGContextSetTextPosition(CGContextRef __nullable c,CGFloatx,CGFloaty)? ? CG_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
1
2
3
1
2
3
12闲孤、繪制CTLine谆级。
voidCTLineDraw(
CTLineRef line,
CGContextRef context )CT_AVAILABLE(10_5,3_2);
1
2
3
1
2
3
13、獲取CTLine的上行高度讼积,下行高度肥照,行距
doubleCTLineGetTypographicBounds(? ? CTLineRef line,CGFloat* __nullable ascent,CGFloat* __nullable descent,CGFloat* __nullable leading ) CT_AVAILABLE(10_5,3_2);
1
2
3
4
5
1
2
3
4
5
14、設(shè)置當(dāng)前文本矩陣
CG_EXTERN voidCGContextSetTextMatrix(CGContextRef __nullable c,
CGAffineTransform t)CG_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
1
2
3
1
2
3
15勤众、獲取一行文字的范圍舆绎,
就是指把這一行文字點(diǎn)有的像素矩陣作為一個image圖片,來得到整個矩形區(qū)域们颜。相對于每一行基線原點(diǎn)的偏移量和寬高(例如:{{1.2吕朵,
-2.57227}, {208.025,
19.2523}},就是相對于本身的基線原點(diǎn)向右偏移1.2個單位窥突,向下偏移2.57227個單位努溃,后面是寬高)
CGRectCTLineGetImageBounds(
CTLineRef line,
CGContextRef __nullable context )CT_AVAILABLE(10_5,3_2);
1
2
3
1
2
3
例如:
//獲取frame中CTLineRef數(shù)組CFArrayRef Lines = CTFrameGetLines(frame);//獲取數(shù)組Lines中的個數(shù)CFIndex lineCount = CFArrayGetCount(Lines);//獲取數(shù)組中第一個CTLineRefCTLineRef lineRef = CFArrayGetValueAtIndex(Lines,0);//獲取lineRef中CTRunRef數(shù)組CFArrayRef runs = CTLineGetGlyphRuns(lineRef);//獲取CTLineRef中字形個數(shù)CFIndex rus = CTLineGetGlyphCount(lineRef);//獲取數(shù)組runs中的個數(shù)CFIndex runCount = CFArrayGetCount(runs);NSLog(@"lines =%ldruns =%ldrus =%ld",lineCount,runCount,rus);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
打印:
lines=7? runs = 5 rus = 37
1
1
- (void)drawRect:(CGRect)rect{// 步驟1:得到當(dāng)前用于繪制畫布的上下文,用于后續(xù)將內(nèi)容繪制在畫布上// 因?yàn)镃ore Text要配合Core Graphic 配合使用的,如Core Graphic一樣第队,繪圖的時(shí)候需要獲得當(dāng)前的上下文進(jìn)行繪制CGContextRef context = UIGraphicsGetCurrentContext();NSLog(@"當(dāng)前context的變換矩陣 %@", NSStringFromCGAffineTransform(CGContextGetCTM(context)));// 步驟2:翻轉(zhuǎn)當(dāng)前的坐標(biāo)系(因?yàn)閷τ诘讓永L制引擎來說哮塞,屏幕左下角為(0,0))CGContextSetTextMatrix(context, CGAffineTransformIdentity);//設(shè)置字形變換矩陣為CGAffineTransformIdentity凳谦,也就是說每一個字形都不做圖形變換CGAffineTransform flipVertical = CGAffineTransformMake(1,0,0,-1,0,self.bounds.size.height);? ? CGContextConcatCTM(context, flipVertical);//將當(dāng)前context的坐標(biāo)系進(jìn)行flipNSLog(@"翻轉(zhuǎn)后context的變換矩陣 %@", NSStringFromCGAffineTransform(CGContextGetCTM(context)));// 步驟3:創(chuàng)建繪制區(qū)域CGMutablePathRef path = CGPathCreateMutable();? ? CGPathAddRect(path,NULL,self.bounds);// 步驟4:創(chuàng)建需要繪制的文字與計(jì)算需要繪制的區(qū)域NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:@"iOS程序在啟動時(shí)會創(chuàng)建一個主線程忆畅,而在一個線程只能執(zhí)行一件事情,如果在主線程執(zhí)行某些耗時(shí)操作尸执,例如加載網(wǎng)絡(luò)圖片邻眷,下載資源文件等會阻塞主線程(導(dǎo)致界面卡死,無法交互)剔交,所以就需要使用多線程技術(shù)來避免這類情況。iOS中有三種多線程技術(shù) NSThread改衩,NSOperation岖常,GCD,這三種技術(shù)是隨著IOS發(fā)展引入的葫督,抽象層次由低到高竭鞍,使用也越來越簡單。"];// 步驟5:根據(jù)AttributedString生成CTFramesetterRefCTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attrString);? ? CTFrameRef frame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, [attrString length]), path,NULL);//獲取frame中CTLineRef數(shù)組CFArrayRef Lines = CTFrameGetLines(frame);//獲取數(shù)組Lines中的個數(shù)CFIndex lineCount = CFArrayGetCount(Lines);//獲取基線原點(diǎn)CGPointorigins[lineCount];? ? CTFrameGetLineOrigins(frame, CFRangeMake(0,0), origins);for(CFIndex i =0; i < lineCount; i ++) {? ? ? ? CTLineRef line = CFArrayGetValueAtIndex(Lines, i);//相對于每一行基線原點(diǎn)的偏移量和寬高(例如:{{1.2橄镜, -2.57227}, {208.025, 19.2523}}偎快,就是相對于本身的基線原點(diǎn)向右偏移1.2個單位,向下偏移2.57227個單位洽胶,后面是寬高)CGRectlineBounds = CTLineGetImageBounds((CTLineRef)line, context);NSLog(@"lineBounds = %@",NSStringFromCGRect(lineBounds));NSLog(@"point = %@",NSStringFromCGPoint(origins[i]));//每一行的起始點(diǎn)(相對于context)加上相對于本身基線原點(diǎn)的偏移量lineBounds.origin.x+= origins[i].x;? ? ? ? lineBounds.origin.y+= origins[i].y;//填充CGContextSetLineWidth(context,1.0);? ? ? ? CGContextAddRect(context,lineBounds);? ? ? ? CGContextSetStrokeColorWithColor(context, [[UIColorredColor] CGColor]);? ? ? ? CGContextStrokeRect(context, lineBounds);? ? }// 步驟6:進(jìn)行繪制CTFrameDraw(frame, context);// 步驟7.內(nèi)存管理CFRelease(frame);? ? CFRelease(path);? ? CFRelease(frameSetter);}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
打由辜小:
當(dāng)前context的變換矩陣 [2,0,0,-2,0,800]翻轉(zhuǎn)后context的變換矩陣 [2,0,0,2,0,0]lineBounds={{0.7734375,-2.052}, {354.70246875000004, 11.964}}point= {0,387}lineBounds={{0.44400000000000001,-2.052}, {371.06400000000002, 11.94}}point= {0,370}lineBounds={{0.38400000000000001,-2.052}, {371.06400000000002, 11.975999999999999}}point= {0,353}lineBounds={{0.41999999999999998,-2.052}, {320.66929687499999, 11.927999999999999}}point= {0,336}lineBounds={{0.9140625,-2.501953125}, {366.28096875, 12.473953125}}point= {0,319}lineBounds={{0.40800000000000003,-2.052}, {148.16400000000002, 11.94}}point= {0,302}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
1
2
3
4
5
6
7
8
9
10
11
12
13
14
- (void)drawRect:(CGRect)rect{// 步驟1:得到當(dāng)前用于繪制畫布的上下文姊氓,用于后續(xù)將內(nèi)容繪制在畫布上// 因?yàn)镃ore Text要配合Core Graphic 配合使用的丐怯,如Core Graphic一樣,繪圖的時(shí)候需要獲得當(dāng)前的上下文進(jìn)行繪制CGContextRef context = UIGraphicsGetCurrentContext();NSLog(@"當(dāng)前context的變換矩陣 %@", NSStringFromCGAffineTransform(CGContextGetCTM(context)));// 步驟2:翻轉(zhuǎn)當(dāng)前的坐標(biāo)系(因?yàn)閷τ诘讓永L制引擎來說翔横,屏幕左下角為(0读跷,0))CGContextSetTextMatrix(context, CGAffineTransformIdentity);//設(shè)置字形變換矩陣為CGAffineTransformIdentity,也就是說每一個字形都不做圖形變換CGAffineTransform flipVertical = CGAffineTransformMake(1,0,0,-1,0,self.bounds.size.height);? ? CGContextConcatCTM(context, flipVertical);//將當(dāng)前context的坐標(biāo)系進(jìn)行flipNSLog(@"翻轉(zhuǎn)后context的變換矩陣 %@", NSStringFromCGAffineTransform(CGContextGetCTM(context)));// 步驟3:創(chuàng)建繪制區(qū)域CGMutablePathRef path = CGPathCreateMutable();? ? CGPathAddRect(path,NULL,self.bounds);// 步驟4:創(chuàng)建需要繪制的文字與計(jì)算需要繪制的區(qū)域NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:@"門梁真可怕 當(dāng)中英文混合之后禾唁,??????????會出現(xiàn)行高不統(tǒng)一的情況效览,現(xiàn)在在繪制的時(shí)候根據(jù)字體的descender來偏移繪制,對齊baseline荡短。??????????同時(shí)點(diǎn)擊鏈接的時(shí)候會調(diào)用drawRect: 造成繪制異常丐枉,所以將setNeedsDisplay注釋,如需刷新肢预,請手動調(diào)用矛洞。帶上emoji以供測試????????????????????"];? ? CTFontRef font = CTFontCreateWithName(CFSTR("Georgia"),20,NULL);? ? [attrString addAttribute:(id)kCTFontAttributeName value:(__bridgeid)font range:NSMakeRange(0, attrString.length)];// 步驟5:根據(jù)AttributedString生成CTFramesetterRefCTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attrString);? ? CTFrameRef frame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, [attrString length]), path,NULL);//獲取frame中CTLineRef數(shù)組CFArrayRef Lines = CTFrameGetLines(frame);//獲取數(shù)組Lines中的個數(shù)CFIndex lineCount = CFArrayGetCount(Lines);//獲取基線原點(diǎn)CGPointorigins[lineCount];? ? CTFrameGetLineOrigins(frame, CFRangeMake(0,0), origins);for(CFIndex i =0; i < lineCount; i ++) {? ? ? ? CTLineRef line = CFArrayGetValueAtIndex(Lines, i);//遍歷每一行CTLineCGFloatlineAscent;CGFloatlineDescent;CGFloatlineLeading;// 行距// 該函數(shù)除了會設(shè)置好ascent,descent,leading之外,還會返回這行的寬度CTLineGetTypographicBounds(line, &lineAscent, &lineDescent, &lineLeading);NSLog(@"lineAscent = %f",lineAscent);NSLog(@"lineDescent = %f",lineDescent);NSLog(@"lineLeading = %f",lineLeading);CGPointlineOrigin = origins[i];NSLog(@"point = %@",NSStringFromCGPoint(lineOrigin));CGRectoldLineBounds = CTLineGetImageBounds((CTLineRef)line, context);NSLog(@"lineBounds改動前:%@",NSStringFromCGRect(oldLineBounds));NSLog(@"y = %f? d = %f? fontD = %f",lineOrigin.y,lineDescent,CTFontGetDescent(font));NSLog(@"Position修改前%@",NSStringFromCGPoint(CGContextGetTextPosition(context)));? ? ? ? CGContextSetTextPosition(context, lineOrigin.x, lineOrigin.y-lineDescent - CTFontGetDescent(font));NSLog(@"Position修改后%@",NSStringFromCGPoint(CGContextGetTextPosition(context)));CGRectlineBounds = CTLineGetImageBounds((CTLineRef)line, context);NSLog(@"lineBounds改動后 = %@",NSStringFromCGRect(lineBounds));//填充CGContextSetLineWidth(context,1.0);? ? ? ? CGContextAddRect(context,lineBounds);? ? ? ? CGContextSetStrokeColorWithColor(context, [[UIColorredColor] CGColor]);? ? ? ? CGContextStrokeRect(context, lineBounds);? ? ? ? CTLineDraw(line, context);//繪制原點(diǎn)為左下角}// 步驟6:進(jìn)行繪制//? ? CTFrameDraw(frame, context);// 步驟7.內(nèi)存管理CFRelease(frame);? ? CFRelease(path);? ? CFRelease(frameSetter);}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
打印數(shù)據(jù):
當(dāng)前context的變換矩陣 [2,0,0, -2,0,800]翻轉(zhuǎn)后context的變換矩陣 [2,0,0,2,0,0]lineAscent =22.000000lineDescent =6.875000lineLeading =0.000000point ={0, 378}lineBounds改動前:{{1.98, -3.5499999999999998},{328.34421874999998, 22}}y =378.000000d =6.875000fontD =4.384766Position修改前{0, 0}Position修改后{0, 366.740234375}lineBounds改動后 ={{1.98, 363.19023437499999},{328.34421874999998, 22}}lineAscent =22.000000lineDescent =6.875000lineLeading =0.000000point ={0, 349}lineBounds改動前:{{331.32421875, 363.19023437499999},{367.41999999999996, 22}}y =349.000000d =6.875000fontD =4.384766Position修改前{330.82421875, 366.740234375}Position修改后{0, 337.740234375}lineBounds改動后 ={{0.5, 334.19023437499999},{367.41999999999996, 22}}lineAscent =21.200000lineDescent =6.800000lineLeading =0.000000point ={0, 321}lineBounds改動前:{{369.83999999999997, 335.58023437499997},{368.16703124999998, 18.66}}y =321.000000d =6.800000fontD =4.384766Position修改前{369, 337.740234375}Position修改后{0, 309.81523437499999}lineBounds改動后 ={{0.83999999999999997, 307.65523437499996},{368.16703124999998, 18.66}}lineAscent =22.000000lineDescent =6.875000lineLeading =0.000000point ={0, 292}lineBounds改動前:{{370.40703124999999, 306.26523437499998},{365.81625000000003, 22}}y =292.000000d =6.875000fontD =4.384766Position修改前{369.70703125, 309.81523437499999}Position修改后{0, 280.740234375}lineBounds改動后 ={{0.70000000000000007, 277.19023437499999},{365.81625000000003, 22}}lineAscent =21.200000lineDescent =6.800000lineLeading =0.000000point ={0, 264}lineBounds改動前:{{368.41624999999999, 278.58023437499997},{353.68367187500002, 18.620000000000001}}y =264.000000d =6.800000fontD =4.384766Position修改前{367.65625, 280.740234375}Position修改后{0, 252.81523437499999}lineBounds改動后 ={{0.76000000000000001, 250.65523437499999},{353.68367187500002, 18.620000000000001}}lineAscent =21.200000lineDescent =6.800000lineLeading =0.000000point ={0, 236}lineBounds改動前:{{356.94367187500001, 248.47929687499999},{363.27226562499999, 20.775937499999998}}y =236.000000d =6.800000fontD =4.384766Position修改前{355.263671875, 252.81523437499999}Position修改后{0, 224.81523437499999}lineBounds改動后 ={{1.6799999999999999, 220.47929687499999},{363.27226562499999, 20.775937499999998}}lineAscent =21.200000lineDescent =6.800000lineLeading =0.000000point ={0, 208}lineBounds改動前:{{367.25226562500001, 220.47929687499999},{328.44562499999995, 20.915937499999998}}y =208.000000d =6.800000fontD =4.384766Position修改前{366.572265625, 224.81523437499999}Position修改后{0, 196.81523437499999}lineBounds改動后 ={{0.68000000000000005, 192.47929687499999},{328.44562499999995, 20.915937499999998}}lineAscent =22.000000lineDescent =6.875000lineLeading =0.000000point ={0, 179}lineBounds改動前:{{330.265625, 193.26523437499998},{229, 22}}y =179.000000d =6.875000fontD =4.384766Position修改前{329.765625, 196.81523437499999}Position修改后{0, 167.740234375}lineBounds改動后 ={{0.5, 164.19023437499999},{229, 22}}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
行高=每行的asent + 每行的descent + 行數(shù)*行間距
.m
#import"MyView.h"#import// 行距constCGFloatkGlobalLineLeading =5.0;@interfaceMyView()@property(nonatomic,assign)CGFloattextHeight;@end@implementationMyView- (instancetype)initWithFrame:(CGRect)frame{self= [superinitWithFrame:frame];if(self) {self.text= @"我自橫刀向天笑沼本,去留肝膽兩昆侖噩峦。--譚嗣同同學(xué)你好啊。This is my first CoreText demo,how are you ?I love three things,the sun,the moon,and you.the sun for the day,the moon for the night,and you forever.??????????????去年今日此門中抽兆,人面桃花相映紅识补。人面不知何處去,桃花依舊笑春風(fēng)辫红。??????????????少年不知愁滋味凭涂,愛上層樓,愛上層樓贴妻,為賦新詞強(qiáng)說愁切油。56321363464.而今識盡愁滋味,欲說還休名惩,欲說還休澎胡,卻道天涼好個秋。123456娩鹉,7890攻谁,56321267895434。缺月掛疏桐弯予,漏斷人初靜戚宦。誰見幽人獨(dú)往來,縹緲孤鴻影锈嫩。驚起卻回頭受楼,有恨無人省。撿盡寒枝不肯棲祠挫,寂寞沙洲冷那槽。";self.font= [UIFontsystemFontOfSize:15];? ? }returnself;}#pragma mark - 計(jì)算高度/**
*? 高度 = 每行的asent + 每行的descent + 行數(shù)*行間距
*? 行間距為指定的數(shù)值
*/+ (CGFloat)textHeightWithText:(NSString*)aText width:(CGFloat)aWidth font:(UIFont*)aFont{? ? NSMutableAttributedString *content = [[NSMutableAttributedString alloc] initWithString:aText];// 設(shè)置全局樣式[selfaddGlobalAttributeWithContent:content font:aFont];? ? CTFramesetterRef framesetterRef = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)content);//粗略的計(jì)算高度CGSizesuggestSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetterRef, CFRangeMake(0, aText.length),NULL, CGSizeMake(aWidth, MAXFLOAT),NULL);? ? CGMutablePathRef path = CGPathCreateMutable();? ? CGPathAddRect(path,NULL, CGRectMake(0,0, aWidth, suggestSize.height*10));// 10這個數(shù)值是隨便給的,主要是為了確保高度足夠CTFrameRef frameRef = CTFramesetterCreateFrame(framesetterRef, CFRangeMake(0, aText.length), path,NULL);? ? CFArrayRef lines = CTFrameGetLines(frameRef);? ? CFIndex lineCount = CFArrayGetCount(lines);CGFloatascent =0;CGFloatdescent =0;CGFloatleading =0;CGFloattotalHeight =0;NSLog(@"計(jì)算高度開始");for(CFIndex i =0; i < lineCount; i++){? ? ? ? CTLineRef lineRef = CFArrayGetValueAtIndex(lines, i);? ? ? ? CTLineGetTypographicBounds(lineRef, &ascent, &descent, &leading);NSLog(@"ascent = %f---descent = %f---leading = %f",ascent,descent,leading);? ? ? ? totalHeight += ascent + descent + kGlobalLineLeading;//行間距}NSLog(@"totalHeight = %f",totalHeight);returntotalHeight;}#pragma mark - 工具方法#pragma mark 給字符串添加全局屬性等舔,比如行距骚灸,字體大小,默認(rèn)顏色+ (void)addGlobalAttributeWithContent:(NSMutableAttributedString *)aContent font:(UIFont*)aFont{CGFloatlineLeading = kGlobalLineLeading;// 行間距constCFIndex kNumberOfSettings =2;//設(shè)置段落格式CTParagraphStyleSetting lineBreakStyle;? ? CTLineBreakMode lineBreakMode = kCTLineBreakByWordWrapping;? ? lineBreakStyle.spec= kCTParagraphStyleSpecifierLineBreakMode;? ? lineBreakStyle.valueSize=sizeof(CTLineBreakMode);? ? lineBreakStyle.value= &lineBreakMode;//設(shè)置行距CTParagraphStyleSetting lineSpaceStyle;? ? CTParagraphStyleSpecifier spec;? ? spec = kCTParagraphStyleSpecifierLineSpacingAdjustment;? ? lineSpaceStyle.spec= spec;? ? lineSpaceStyle.valueSize=sizeof(CGFloat);? ? lineSpaceStyle.value= &lineLeading;// 結(jié)構(gòu)體數(shù)組CTParagraphStyleSetting theSettings[kNumberOfSettings] = {? ? ? ? lineBreakStyle,? ? ? ? lineSpaceStyle,? ? };? ? CTParagraphStyleRef theParagraphRef = CTParagraphStyleCreate(theSettings, kNumberOfSettings);// 將設(shè)置的行距應(yīng)用于整段文字[aContent addAttribute:NSParagraphStyleAttributeName value:(__bridgeid)(theParagraphRef) range:NSMakeRange(0, aContent.length)];? ? CFStringRef fontName = (__bridge CFStringRef)aFont.fontName;? ? CTFontRef fontRef = CTFontCreateWithName(fontName, aFont.pointSize,NULL);// 將字體大小應(yīng)用于整段文字[aContent addAttribute:NSFontAttributeName value:(__bridgeid)fontRef range:NSMakeRange(0, aContent.length)];// 給整段文字添加默認(rèn)顏色[aContent addAttribute:NSForegroundColorAttributeName value:[UIColorblackColor] range:NSMakeRange(0, aContent.length)];// 內(nèi)存管理CFRelease(theParagraphRef);? ? CFRelease(fontRef);}/**
*? 一行一行繪制慌植,未調(diào)整行高(行高不固定)
*/- (void)drawRectWithLineByLine{// 1.創(chuàng)建需要繪制的文字NSMutableAttributedString *attributed = [[NSMutableAttributedString alloc] initWithString:self.text];// 2.設(shè)置行距等樣式[[selfclass] addGlobalAttributeWithContent:attributed font:self.font];self.textHeight= [[selfclass] textHeightWithText:self.textwidth:CGRectGetWidth(self.bounds) font:self.font];// 3.創(chuàng)建繪制區(qū)域甚牲,path的高度對繪制有直接影響,如果高度不夠蝶柿,則計(jì)算出來的CTLine的數(shù)量會少一行或者少多行CGMutablePathRef path = CGPathCreateMutable();? ? CGPathAddRect(path,NULL, CGRectMake(0,0, CGRectGetWidth(self.bounds),self.textHeight));// 4.根據(jù)NSAttributedString生成CTFramesetterRefCTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attributed);? ? CTFrameRef ctFrame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, attributed.length), path,NULL);// 1.獲取上下文CGContextRef contextRef = UIGraphicsGetCurrentContext();// 2.轉(zhuǎn)換坐標(biāo)系CGContextSetTextMatrix(contextRef, CGAffineTransformIdentity);? ? CGContextTranslateCTM(contextRef,0,self.textHeight);// 此處用計(jì)算出來的高度CGContextScaleCTM(contextRef,1.0, -1.0);// 重置高度//? ? CGPathAddRect(path, NULL, CGRectMake(0, 0, CGRectGetWidth(self.bounds), self.textHeight));// 一行一行繪制CFArrayRef lines = CTFrameGetLines(ctFrame);? ? CFIndex lineCount = CFArrayGetCount(lines);CGPointlineOrigins[lineCount];// 把ctFrame里每一行的初始坐標(biāo)寫到數(shù)組里丈钙,注意CoreText的坐標(biāo)是左下角為原點(diǎn)CTFrameGetLineOrigins(ctFrame, CFRangeMake(0,0), lineOrigins);for(inti =0; i < lineCount; i++){CGPointpoint = lineOrigins[i];NSLog(@"point.y = %f",point.y);? ? }NSLog(@"font.ascender = %f,descender = %f,lineHeight = %f,leading = %f",self.font.ascender,self.font.descender,self.font.lineHeight,self.font.leading);CGFloatframeY =0;for(CFIndex i =0; i < lineCount; i++){// 遍歷每一行CTLineCTLineRef line = CFArrayGetValueAtIndex(lines, i);CGFloatlineAscent;CGFloatlineDescent;CGFloatlineLeading;// 行距// 該函數(shù)除了會設(shè)置好ascent,descent,leading之外,還會返回這行的寬度CTLineGetTypographicBounds(line, &lineAscent, &lineDescent, &lineLeading);NSLog(@"lineAscent = %f",lineAscent);NSLog(@"lineDescent = %f",lineDescent);NSLog(@"lineLeading = %f",lineLeading);CGPointlineOrigin = lineOrigins[i];NSLog(@"i = %ld, lineOrigin = %@",i,NSStringFromCGPoint(lineOrigin));// 微調(diào)Y值交汤,需要注意的是CoreText的Y值是在baseLine處雏赦,而不是下方的descent劫笙。// lineDescent為正數(shù),self.font.descender為負(fù)數(shù)if(i >0){// 第二行之后需要計(jì)算frameY = frameY - kGlobalLineLeading - lineAscent;? ? ? ? ? ? lineOrigin.y= frameY;? ? ? ? }else{// 第一行可直接用frameY = lineOrigin.y;? ? ? ? }// 調(diào)整坐標(biāo)CGContextSetTextPosition(contextRef, lineOrigin.x, lineOrigin.y);? ? ? ? CTLineDraw(line, contextRef);// 微調(diào)frameY = frameY - lineDescent;? ? }? ? CFRelease(path);? ? CFRelease(framesetter);? ? CFRelease(ctFrame);}- (void)drawRect:(CGRect)rect{? ? [selfdrawRectWithLineByLine];}@end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
.h文件
#import@interfaceMyView:UIView@property(nonatomic,copy)NSString*text;@property(nonatomic,strong)UIFont*font;+ (CGFloat)textHeightWithText:(NSString*)aText width:(CGFloat)aWidth font:(UIFont*)aFont;@end
1
2
3
4
5
6
7
8
9
10
11
1
2
3
4
5
6
7
8
9
10
11
結(jié)果:
總高度 = 行數(shù)*每行的高度
.m
#import"MyView.h"#import// 行距constCGFloatkGlobalLineLeading =5.0;// 在15字體下填大,比值小于這個計(jì)算出來的高度會導(dǎo)致emoji顯示不全constCGFloatkPerLineRatio =1.4;@interfaceMyView()@property(nonatomic,assign)CGFloattextHeight;@end@implementationMyView- (instancetype)initWithFrame:(CGRect)frame{self= [superinitWithFrame:frame];if(self) {self.text= @"我自橫刀向天笑,去留肝膽兩昆侖俏橘。--譚嗣同同學(xué)你好啊允华。This is my first CoreText demo,how are you ?I love three things,the sun,the moon,and you.the sun for the day,the moon for the night,and you forever.??????????????去年今日此門中,人面桃花相映紅寥掐。人面不知何處去靴寂,桃花依舊笑春風(fēng)。??????????????少年不知愁滋味召耘,愛上層樓百炬,愛上層樓,為賦新詞強(qiáng)說愁污它。56321363464.而今識盡愁滋味收壕,欲說還休,欲說還休轨蛤,卻道天涼好個秋。123456虫埂,7890祥山,56321267895434。缺月掛疏桐掉伏,漏斷人初靜缝呕。誰見幽人獨(dú)往來,縹緲孤鴻影斧散。驚起卻回頭供常,有恨無人省。撿盡寒枝不肯棲鸡捐,寂寞沙洲冷栈暇。";self.font= [UIFontsystemFontOfSize:15];? ? }returnself;}/**
*? 高度 = 每行的固定高度 * 行數(shù)
*/+ (CGFloat)textHeightWithText:(NSString*)aText width:(CGFloat)aWidth font:(UIFont*)aFont{? ? NSMutableAttributedString *content = [[NSMutableAttributedString alloc] initWithString:aText];// 給字符串設(shè)置字體行距等樣式[selfaddGlobalAttributeWithContent:content font:aFont];? ? CTFramesetterRef framesetterRef = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)content);// 粗略的高度,該高度不準(zhǔn)箍镜,僅供參考CGSizesuggestSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetterRef, CFRangeMake(0, content.length),NULL, CGSizeMake(aWidth, MAXFLOAT),NULL);NSLog(@"suggestHeight = %f",suggestSize.height);? ? CGMutablePathRef pathRef = CGPathCreateMutable();? ? CGPathAddRect(pathRef,NULL, CGRectMake(0,0, aWidth, suggestSize.height));? ? CTFrameRef frameRef = CTFramesetterCreateFrame(framesetterRef, CFRangeMake(0, content.length), pathRef,NULL);? ? CFArrayRef lines = CTFrameGetLines(frameRef);? ? CFIndex lineCount = CFArrayGetCount(lines);NSLog(@"行數(shù) = %ld",lineCount);// 總高度 = 行數(shù)*每行的高度源祈,其中每行的高度為指定的值,不同字體大小不一樣CGFloataccurateHeight = lineCount * (aFont.pointSize* kPerLineRatio);CGFloatheight = accurateHeight;? ? CFRelease(pathRef);? ? CFRelease(frameRef);returnheight;}#pragma mark - 工具方法#pragma mark 給字符串添加全局屬性色迂,比如行距香缺,字體大小,默認(rèn)顏色+ (void)addGlobalAttributeWithContent:(NSMutableAttributedString *)aContent font:(UIFont*)aFont{CGFloatlineLeading = kGlobalLineLeading;// 行間距constCFIndex kNumberOfSettings =2;//設(shè)置段落格式CTParagraphStyleSetting lineBreakStyle;? ? CTLineBreakMode lineBreakMode = kCTLineBreakByWordWrapping;? ? lineBreakStyle.spec= kCTParagraphStyleSpecifierLineBreakMode;? ? lineBreakStyle.valueSize=sizeof(CTLineBreakMode);? ? lineBreakStyle.value= &lineBreakMode;//設(shè)置行距CTParagraphStyleSetting lineSpaceStyle;? ? CTParagraphStyleSpecifier spec;? ? spec = kCTParagraphStyleSpecifierLineSpacingAdjustment;? ? lineSpaceStyle.spec= spec;? ? lineSpaceStyle.valueSize=sizeof(CGFloat);? ? lineSpaceStyle.value= &lineLeading;// 結(jié)構(gòu)體數(shù)組CTParagraphStyleSetting theSettings[kNumberOfSettings] = {? ? ? ? lineBreakStyle,? ? ? ? lineSpaceStyle,? ? };? ? CTParagraphStyleRef theParagraphRef = CTParagraphStyleCreate(theSettings, kNumberOfSettings);// 將設(shè)置的行距應(yīng)用于整段文字[aContent addAttribute:NSParagraphStyleAttributeName value:(__bridgeid)(theParagraphRef) range:NSMakeRange(0, aContent.length)];? ? CFStringRef fontName = (__bridge CFStringRef)aFont.fontName;? ? CTFontRef fontRef = CTFontCreateWithName(fontName, aFont.pointSize,NULL);// 將字體大小應(yīng)用于整段文字[aContent addAttribute:NSFontAttributeName value:(__bridgeid)fontRef range:NSMakeRange(0, aContent.length)];// 給整段文字添加默認(rèn)顏色[aContent addAttribute:NSForegroundColorAttributeName value:[UIColorblackColor] range:NSMakeRange(0, aContent.length)];// 內(nèi)存管理CFRelease(theParagraphRef);? ? CFRelease(fontRef);}#pragma mark - 一行一行繪制歇僧,行高確定图张,行與行之間對齊- (void)drawRectWithLineByLineAlignment{// 1.創(chuàng)建需要繪制的文字NSMutableAttributedString *attributed = [[NSMutableAttributedString alloc] initWithString:self.text];// 2.設(shè)置行距等樣式[[selfclass] addGlobalAttributeWithContent:attributed font:self.font];self.textHeight= [[selfclass] textHeightWithText:self.textwidth:CGRectGetWidth(self.bounds) font:self.font];// 3.創(chuàng)建繪制區(qū)域,path的高度對繪制有直接影響,如果高度不夠祸轮,則計(jì)算出來的CTLine的數(shù)量會少一行或者少多行CGMutablePathRef path = CGPathCreateMutable();? ? CGPathAddRect(path,NULL, CGRectMake(0,0, CGRectGetWidth(self.bounds),self.textHeight*2));// 4.根據(jù)NSAttributedString生成CTFramesetterRefCTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attributed);? ? CTFrameRef ctFrame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, attributed.length), path,NULL);// 獲取上下文CGContextRef contextRef = UIGraphicsGetCurrentContext();// 轉(zhuǎn)換坐標(biāo)系CGContextSetTextMatrix(contextRef, CGAffineTransformIdentity);? ? CGContextTranslateCTM(contextRef,0,self.textHeight);// 此處用計(jì)算出來的高度CGContextScaleCTM(contextRef,1.0, -1.0);// 一行一行繪制CFArrayRef lines = CTFrameGetLines(ctFrame);? ? CFIndex lineCount = CFArrayGetCount(lines);CGPointlineOrigins[lineCount];// 把ctFrame里每一行的初始坐標(biāo)寫到數(shù)組里兽埃,注意CoreText的坐標(biāo)是左下角為原點(diǎn)CTFrameGetLineOrigins(ctFrame, CFRangeMake(0,0), lineOrigins);for(inti =0; i < lineCount; i++)? ? {CGPointpoint = lineOrigins[i];NSLog(@"point.y = %f",point.y);? ? }NSLog(@"font.ascender = %f,descender = %f,lineHeight = %f,leading = %f",self.font.ascender,self.font.descender,self.font.lineHeight,self.font.leading);CGFloatframeY =0;NSLog(@"self.textHeight = %f,lineHeight = %f",self.textHeight,self.font.pointSize* kPerLineRatio);for(CFIndex i =0; i < lineCount; i++){// 遍歷每一行CTLineCTLineRef line = CFArrayGetValueAtIndex(lines, i);CGFloatlineAscent;CGFloatlineDescent;CGFloatlineLeading;// 行距// 該函數(shù)除了會設(shè)置好ascent,descent,leading之外,還會返回這行的寬度CTLineGetTypographicBounds(line, &lineAscent, &lineDescent, &lineLeading);NSLog(@"lineAscent = %f",lineAscent);NSLog(@"lineDescent = %f",lineDescent);NSLog(@"lineLeading = %f",lineLeading);CGPointlineOrigin = lineOrigins[i];NSLog(@"i = %ld, lineOrigin = %@",i,NSStringFromCGPoint(lineOrigin));// 微調(diào)Y值倔撞,需要注意的是CoreText的Y值是在baseLine處讲仰,而不是下方的descent。CGFloatlineHeight =self.font.pointSize* kPerLineRatio;? ? ? ? frameY =self.textHeight- (i +1)*lineHeight -self.font.descender;NSLog(@"frameY = %f",frameY);? ? ? ? lineOrigin.y= frameY;// 調(diào)整坐標(biāo)CGContextSetTextPosition(contextRef, lineOrigin.x, lineOrigin.y);? ? ? ? CTLineDraw(line, contextRef);? ? }? ? CFRelease(path);? ? CFRelease(framesetter);? ? CFRelease(ctFrame);}- (void)drawRect:(CGRect)rect{? ? [selfdrawRectWithLineByLineAlignment];}@end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
.h
#import@interfaceMyView:UIView@property(nonatomic,copy)NSString*text;@property(nonatomic,strong)UIFont*font;+ (CGFloat)textHeightWithText:(NSString*)aText width:(CGFloat)aWidth font:(UIFont*)aFont;@end
1
2
3
4
5
6
7
8
9
10
11
1
2
3
4
5
6
7
8
9
10
11
結(jié)果
頂
0
踩
0
我的同類文章
iOS連載(8)
?CoreText(五):省略號2016-09-19閱讀293
?CoreText(三):繪制文本2016-08-31閱讀210
?CoreText(一):基本用法2016-08-30閱讀128
?顏色(二):CGColor2016-01-09閱讀257
?CoreText(四):圖文混排2016-08-31閱讀241
?CoreText(二):段落CTParagraphStyle2016-08-31閱讀195
?顏色(三):CIColor2016-01-09閱讀137
?顏色(一):UIColor2016-01-09閱讀197
參考知識庫
1792關(guān)注|395收錄
猜你在找
iOS8開發(fā)技術(shù)(Swift版):屏幕適配
iOS8開發(fā)視頻教程Swift語言版-Part 3:iOS 8多分辨率屏幕適配
iOS企業(yè)級應(yīng)用開發(fā)-iOS6定位服務(wù)與地圖
javascript對象小探之四---undefinednullNaN的相互運(yùn)算
Nodejs 在命令行下執(zhí)行Consolelog命令時(shí)第二行會打印undefined的原因
關(guān)于coretext繪圖字體始終無法改變大小的原因
暫無評論
* 以上用戶言論只代表其個人觀點(diǎn)痪蝇,不代表CSDN網(wǎng)站的觀點(diǎn)或立場
全部主題HadoopAWS移動游戲JavaAndroidiOSSwift智能硬件DockerOpenStackVPNSparkERPIE10EclipseCRMJavaScript數(shù)據(jù)庫UbuntuNFCWAPjQueryBIHTML5SpringApache.NETAPIHTMLSDKIISFedoraXMLLBSUnitySplashtopUMLcomponentsWindows MobileRailsQEMUKDECassandraCloudStackFTCcoremailOPhoneCouchBase云計(jì)算iOS6RackspaceWeb AppSpringSideMaemoCompuware大數(shù)據(jù)aptechPerlTornadoRubyHibernateThinkPHPHBasePureSolrAngularCloud FoundryRedisScalaDjangoBootstrap
個人資料
訪問:69977次
積分:1736
等級:
排名:第16926名
原創(chuàng):104篇
轉(zhuǎn)載:4篇
譯文:0篇
評論:3條
文章搜索
文章分類
瘋狂iOS(上)(12)
瘋狂iOS(下)(11)
iOS多線程和推送(11)
iOS管理(7)
iOS崩潰(3)
iOS總結(jié)(11)
iOS控件(1)
iOS基礎(chǔ)(6)
iOS三方庫(8)
iOS連載(9)
iOS視圖切換(4)
iOS動畫(7)
iOS 8 新增控件(3)
iOS 9 新特性(7)
iOS提高(8)
閱讀排行
第十章:使用MapKit開發(fā)地圖服務(wù)(3979)
自動引用計(jì)數(shù)(3516)
block(3360)
第六章:加速計(jì)與陀螺儀(3271)
BlocksKit的使用(3136)
第九章:使用CoreLocation定位(3111)
第七章:多線程(2984)
第五章:管理手機(jī)(2859)
第四章:多媒體應(yīng)用開發(fā)(2794)
第三章:iOS的數(shù)據(jù)存儲與IO(2768)
評論排行
第七章:多線程(2)
iOS 常用公共方法(1)
第三章:C語言特性(0)
HTTP協(xié)議(0)
推薦文章
* Chromium擴(kuò)展(Extension)的頁面(Page)加載過程分析
* 手把手教你做音樂播放器(二)技術(shù)原理與框架設(shè)計(jì)
* JVM 性能調(diào)優(yōu)實(shí)戰(zhàn)之:使用阿里開源工具 TProfiler 在海量業(yè)務(wù)代碼中精確定位性能代碼
最新評論
那個小五先生:Cool
xiaoxiaobukuang:@goldenepoch:第一個評論,多謝u飭3梅!以后多多指教
goldenepoch:介紹的很詳細(xì)
公司簡介|招賢納士|廣告服務(wù)|銀行匯款帳號|聯(lián)系方式|版權(quán)聲明|法律顧問|問題報(bào)告|合作伙伴|論壇反饋
網(wǎng)站客服雜志客服微博客服webmaster@csdn.net400-600-2320|北京創(chuàng)新樂知信息技術(shù)有限公司 版權(quán)所有|江蘇樂知網(wǎng)絡(luò)技術(shù)有限公司 提供商務(wù)支持
京?ICP?證?09002463?號|Copyright ? 1999-2016, CSDN.NET, All Rights Reserved