可折疊Label

41562293477_.pic.jpg

31562293476_.pic.jpg

ezgif.com-video-to-gif.gif

下載地址: https://github.com/RainbowWait/-Label.git

下面就來詳情看看字形的各個參數(shù)也就是所謂的字形度量Glyph Metrics

1.png
信息 說明
Origin 表示位于基線上的焰络、一個字形在排列時基于基線的原點(diǎn)
Baseline 表示字形在排列時,字形底部緊靠著的一條直線
Line height 表示一行字形最大高度,等于Ascent 和 Decent(取其絕對值)及 Line gap(leading)三者之和
Ascent 表示上行高度,是基線與字形最高點(diǎn)之間的距離
Descent 表示下行調(diào)試,是基線與字形最低點(diǎn)之間的距離
Line gap(leading) 表示行距,是上方一行的最低點(diǎn)與下方一行的最高點(diǎn)的距離
Advancement 表示簽好兩個字形的原點(diǎn)之間的距離
Bounding rectangle 能夠容納字形的最小矩形形框
Italic angle 斜體字形在垂直方向上沿順時針的傾斜角度
X-height 基線至非突出的小寫字母(如a戴甩、x、e等)最高點(diǎn)的距離
Cap height 基線至大寫字母最高點(diǎn)的距離

lineHeight = ascent + |descent| + leading

行高 = 上行高度 + 下行高度的絕對值 + 行間距

二闪彼、坐標(biāo)系

傳統(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)就在左上角。

iOS UIKit中描馅,UIView是以左上角為原點(diǎn)把夸,而Core Text一開始的定位是使用與桌面應(yīng)用的排版系統(tǒng),桌面應(yīng)用的坐標(biāo)系是以左下角為原點(diǎn)流昏,即Core Text在繪制的時候也是參照左下角為原點(diǎn)進(jìn)行繪制的扎即,所以需要對當(dāng)前的坐標(biāo)系進(jìn)行處理。

實(shí)際上况凉,Core Graphic 中的context也是以左下角為原點(diǎn)的谚鄙, 但是為什么我們用Core Graphic 繪制一些簡單的圖形的時候不需要對坐標(biāo)系進(jìn)行處理呢,是因?yàn)橥ㄟ^這個方法UIGraphicsGetCurrentContext()來獲得的當(dāng)前context是已經(jīng)被處理過的了刁绒,用下面方法可以查看指定的上下文的當(dāng)前圖形狀態(tài)變換矩陣闷营。

  • 方法一
//因?yàn)镃ore Text要配合Core Graphic 配合使用的,如Core Graphic一樣知市,繪圖的時候需要獲得當(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)行flip 

NSLog(@"翻轉(zhuǎn)后context的變換矩陣 %@", NSStringFromCGAffineTransform(CGContextGetCTM(context))); 
  • 方法二
//因?yàn)镃ore Text要配合Core Graphic 配合使用的娘赴,如Core Graphic一樣,繪圖的時候需要獲得當(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);
CGContextTranslateCTM(context, 0, self.bounds.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
NSLog(@"翻轉(zhuǎn)后context的變換矩陣 %@", NSStringFromCGAffineTransform(CGContextGetCTM(context)));
CocreText類 類說明
CTFramesetter 生成CTFrame的類型
CTFrame 文本幀,包含多個CTLine
CTLine 一行文本,一行文本包括多個屬性不同的CTRun
CTRun 共享相同屬性和方向的連續(xù)字形
2.png

CTFrame 作為一個整體的畫布(Canvas),其中由行(CTLine)組成隅肥,而每行可以分為一個或多個小方塊(CTRun)

注意:你不需要自己創(chuàng)建CTRun竿奏,Core Text將根據(jù)NSAttributedString的屬性來自動創(chuàng)建CTRun。每個CTRun對象對應(yīng)不同的屬性腥放,正因此泛啸,你可以自由的控制字體、顏色秃症、字間距等等信息

NSAttributedString
CGPathRef path = CGPathCreateWithRect(CGRectMake(0, 0, self.bounds.size.width, UIScreen.mainScreen.bounds.size.height), nil); 

NSMutableAttributedString *drawAttributedText1 = [[NSMutableAttributedString alloc] initWithAttributedString:_attributedText]; 
CTFramesetterRef CTFramesetterCreateWithAttributedString(CFAttributedStringRef string) 
CTFramesetter
CTFramesetterRef setter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)drawAttributedText);  
  • 通過屬性字符串創(chuàng)建CTFramesetterRef對象
CTFramesetterRef CTFramesetterCreateWithAttributedString(CFAttributedStringRef string);
  • CTFramesetterRef對象創(chuàng)建幀對象(CTFrameRef)
CTFrameRef CTFramesetterCreateFrame(CTFramesetterRef framesetter, CFRange stringRange, CGPathRef path, CFDictionaryRef frameAttributes);
  • 獲得推薦的文本尺寸大小
CGSize CTFramesetterSuggestFrameSizeWithConstraints(CTFramesetterRef framesetter, CFRange stringRange, CFDictionaryRef frameAttributes, CGSize constraints, CFRange *fitRange);
CTFrameRef
CTFrameRef ctFrame = CTFramesetterCreateFrame(setter, CFRangeMake(0, drawAttributedText.length), path, NULL); 
  • 通過CTFrameRef幀率獲得行數(shù)CTLineRef對象
CFArrayRef CTFrameGetLines(CTFrameRef frame);
  • 通過幀率獲取每行的位置

Origins 傳的是指針 所以該參數(shù)定義成CGPoint origins = [lines.count] lines是行數(shù)

void CTFrameGetLineOrigins(CTFrameRef frame, CFRange range, CGPoint *origins);
CTLines
NSArray *lines = (NSArray*)CTFrameGetLines(ctFrame); 
  • 獲取該行包含的CTRunRef
CFArrayRef CTLineGetGlyphRuns(CTLineRef line);
  • 通過屬性字符串創(chuàng)建CTLineRef對象
CTLineRef CTLineCreateWithAttributedString(CFAttributedStringRef attrString)
  • 獲取行所在的下標(biāo)位置
CFIndex CTLineGetGlyphCount(CTLineRef line);
  • 獲取該行在整個文本幀的位置
CFRange CTLineGetStringRange(CTLineRef line);
  • 獲取改行的上行高候址、下行高、行間距(行高)
double CTLineGetTypographicBounds(CTLineRef line, CGFloat *ascent, CGFloat *descent, CGFloat *leading);
//行高 lineHeightErrorDimension誤差 可以為0  lineSpace 設(shè)置的行間距
-(CGFloat)heightForCTLine: (CTLineRef)line{
    CGFloat h = 0;
    CGFloat ascent;
    CGFloat descent;
    CGFloat leading;
    CTLineGetTypographicBounds(line, &ascent, &descent, &leading);
    h = MAX(h, ascent + descent + leading);
    return h + _lineHeightErrorDimension + self.lineSpace;
}
//行間距的設(shè)置方式
- (void)addGlobalAttributeWithContent:(NSMutableAttributedString *)aContent font:(UIFont *)aFont
{
    CGFloat lineLeading = self.lineSpace; // 行間距
    
    const CFIndex 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] = {
        lineSpaceStyle,
    };
    CTParagraphStyleRef theParagraphRef = CTParagraphStyleCreate(theSettings, kNumberOfSettings);
    
    // 將設(shè)置的行距應(yīng)用于整段文字
    [aContent addAttribute:NSParagraphStyleAttributeName value:(__bridge id)(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:(__bridge id)fontRef range:NSMakeRange(0, aContent.length)];
//
//    // 給整段文字添加默認(rèn)顏色
//    [aContent addAttribute:NSForegroundColorAttributeName value:[UIColor blackColor] range:NSMakeRange(0, aContent.length)];
    // 內(nèi)存管理
    CFRelease(theParagraphRef);
//    CFRelease(fontRef);
}
CTRunRef
CTLineRef line = (__bridge CTLineRef)lines[i]; 

NSArray *runs = (NSArray*)CTLineGetGlyphRuns(line);
  • 獲取改行的CTRun塊在該行的下標(biāo)位置
CFIndex CTRunGetGlyphCount(CTRunRef run);
  • 獲取該行的CTRun塊在的物理坐標(biāo)位置
const CGPoint * CTRunGetPositionsPtr(CTRunRef run);
  • 獲取改CTRun塊的寬度 返回值是邊界寬度
double CTRunGetTypographicBounds(CTRunRef run, CFRange range, CGFloat *ascent, CGFloat *descent, CGFloat *leading);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末种柑,一起剝皮案震驚了整個濱河市宗雇,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌莹规,老刑警劉巖霹俺,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異拷橘,居然都是意外死亡睦番,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進(jìn)店門母市,熙熙樓的掌柜王于貴愁眉苦臉地迎上來矾兜,“玉大人,你說我怎么就攤上這事患久∫嗡拢” “怎么了浑槽?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長返帕。 經(jīng)常有香客問我桐玻,道長,這世上最難降的妖魔是什么荆萤? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任镊靴,我火速辦了婚禮,結(jié)果婚禮上链韭,老公的妹妹穿的比我還像新娘偏竟。我一直安慰自己,他們只是感情好敞峭,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布踊谋。 她就那樣靜靜地躺著,像睡著了一般旋讹。 火紅的嫁衣襯著肌膚如雪褪子。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天骗村,我揣著相機(jī)與錄音嫌褪,去河邊找鬼。 笑死胚股,一個胖子當(dāng)著我的面吹牛笼痛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播琅拌,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼缨伊,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了进宝?” 一聲冷哼從身側(cè)響起刻坊,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎党晋,沒想到半個月后谭胚,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡未玻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年灾而,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片扳剿。...
    茶點(diǎn)故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡旁趟,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出庇绽,到底是詐尸還是另有隱情锡搜,我是刑警寧澤橙困,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站耕餐,受9級特大地震影響凡傅,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蛾方,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望上陕。 院中可真熱鬧桩砰,春花似錦、人聲如沸释簿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽庶溶。三九已至煮纵,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間偏螺,已是汗流浹背行疏。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留套像,地道東北人酿联。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像夺巩,于是被迫代替她去往敵國和親贞让。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評論 2 355

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

  • 最近一直沒有更新簡書是因?yàn)樵陂_發(fā)和測試階段柳譬,有任務(wù)喳张,沒有進(jìn)行學(xué)習(xí),不過在做任務(wù)的時候也遇到了一些技術(shù)點(diǎn)美澳,在這里總結(jié)...
    和玨貓閱讀 4,471評論 8 8
  • 源碼在這里 销部,使用Cocoapod: 簡介 設(shè)置一段顯示不完整文字省略號后的折疊按鈕。先看效果: 功能亮點(diǎn):1.用...
    rookiesss閱讀 1,332評論 1 5
  • 》》銜接上一篇 145 白蓮國制跟,太子?xùn)|宮柴墩, 雕梁畫棟,碧瓦飛甍凫岖,皇上皇后都坐在一旁江咳,太子端坐木質(zhì)的椅子上,這木質(zhì)的...
    幽小窗閱讀 534評論 42 28
  • 一整晚哥放,寶貝仍反復(fù)發(fā)燒歼指。早上六點(diǎn)多爹土,再次量體溫還是38℃,心里正糾結(jié)著是去醫(yī)院呢還是去上學(xué)踩身?寶貝立即喊道說今...
    小軒仔0808閱讀 92評論 0 0
  • 第二次世界大戰(zhàn)初期胀茵,為了抵御德軍的閃電戰(zhàn),英國的海軍和空軍嚴(yán)陣以待挟阻,特別對英 吉利海峽這一海上要塞更是重兵防范琼娘。 ...
    今夜有風(fēng)3閱讀 502評論 0 6