CoreText使用教程(一)

本篇教程爲第一篇,僅實如今一個UIView的子控件上繪製純文本。php

Github地址:https://github.com/JlongTian/JLCoreTextOnehtml

學習CoreText須要有一些基礎知識儲備,關於字符和字形的知識請點擊這裏以及這裏。另外還須要對NSAttributedString有一些瞭解,CoreText對文本和圖片的繪製就是依賴於NSAttributedString屬性字符串的。ios

說下CoreText的繪製過程,先上一張圖片:git

整個流程大概是:獲取上下文-》翻轉座標系-》建立NSAttributedString-》根據NSAttributedString建立CTFramesetterRef-》建立繪製區域CGPathRef-》根據CTFramesetterRef和CGPathRef建立CTFrame-》CTFrameDraw繪製。github

上圖大概顯示了後半部分的結構。 CTFrame是指整個該UIView子控件的繪製區域,CTLine則是指每一行,CTRun則是每一段具備同樣屬性的字符串。好比某段字體大小、顏色都一致的字符串爲一個CTRun,CTRun不能夠跨行,無論屬性一致或不一致。一般的結構是每個CTFrame有多個CTLine,每個CTLine有多個CTRun。數組

本次純文本實現的效果圖以下:學習

控制器的代碼處理很簡單,UIView子控件的drawRect的代碼以下:字體

-(void)drawRect:(CGRect)rect{
    
    [super drawRect:rect];
    
    // 1.獲取上下文
    CGContextRef contextRef = UIGraphicsGetCurrentContext();
    
    // [a,b,c,d,tx,ty]
    NSLog(@"轉換前的座標:%@",NSStringFromCGAffineTransform(CGContextGetCTM(contextRef)));
    
    // 2.轉換座標系,CoreText的原點在左下角,UIKit原點在左上角
    CGContextSetTextMatrix(contextRef, CGAffineTransformIdentity);
    
    // 這兩種轉換座標的方式效果同樣
    // 2.1
    // CGContextTranslateCTM(contextRef, 0, self.bounds.size.height);
    // CGContextScaleCTM(contextRef, 1.0, -1.0);
    
    // 2.2
    CGContextConcatCTM(contextRef, CGAffineTransformMake(1, 0, 0, -1, 0, self.bounds.size.height));
    
    NSLog(@"轉換後的座標:%@",NSStringFromCGAffineTransform(CGContextGetCTM(contextRef)));
    
    
    // 3.建立繪製區域,能夠對path進行個性化裁剪以改變顯示區域
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathAddRect(path, NULL, self.bounds);
    // CGPathAddEllipseInRect(path, NULL, self.bounds);
    
    // 4.建立須要繪製的文字
    NSMutableAttributedString *attributed = [[NSMutableAttributedString alloc] initWithString:@"這是個人第一個coreText demo,我是要給兵來自老白乾I型那個餓哦個呢給個I類回滾yes we can 評估後共和國開不開vbdkaphphohghg 的分工額好幾個遼寧省更怕hi維護你不看hi好人佛【井柏然把餓哦個"];
    
    [attributed addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:20] range:NSMakeRange(0, 5)];
    
    // 兩種方式皆可
    [attributed addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(3, 10)];
    [attributed addAttribute:(id)kCTForegroundColorAttributeName value:[UIColor greenColor] range:NSMakeRange(0, 2)];
    
    // 設置行距等樣式
    CGFloat lineSpace = 10; // 行距通常取決於這個值
    CGFloat lineSpaceMax = 20;
    CGFloat lineSpaceMin = 2;
    const CFIndex kNumberOfSettings = 3;
    
    // 結構體數組
    CTParagraphStyleSetting theSettings[kNumberOfSettings] = {
        
        {kCTParagraphStyleSpecifierLineSpacingAdjustment,sizeof(CGFloat),&lineSpace},
        {kCTParagraphStyleSpecifierMaximumLineSpacing,sizeof(CGFloat),&lineSpaceMax},
        {kCTParagraphStyleSpecifierMinimumLineSpacing,sizeof(CGFloat),&lineSpaceMin}
        
    };
    CTParagraphStyleRef theParagraphRef = CTParagraphStyleCreate(theSettings, kNumberOfSettings);
    
    // 單個元素的形式
    // CTParagraphStyleSetting theSettings = {kCTParagraphStyleSpecifierLineSpacingAdjustment,sizeof(CGFloat),&lineSpace};
    // CTParagraphStyleRef theParagraphRef = CTParagraphStyleCreate(&theSettings, kNumberOfSettings);
    
    // 兩種方式皆可
    // [attributed addAttribute:(id)kCTParagraphStyleAttributeName value:(__bridge id)theParagraphRef range:NSMakeRange(0, attributed.length)];
    
    // 將設置的行距應用於整段文字
    [attributed addAttribute:NSParagraphStyleAttributeName value:(__bridge id)(theParagraphRef) range:NSMakeRange(0, attributed.length)];
    
    CFRelease(theParagraphRef);
    
    //設置字間距
    long number = 2.0;
    CFNumberRef num = CFNumberCreate(kCFAllocatorDefault,kCFNumberSInt8Type,&number);
    [attributed addAttribute:(id)kCTKernAttributeName value:(__bridge id)num range:NSMakeRange(0,[attributed length])];
    
    CFRelease(num);
    
    
    // 5.根據NSAttributedString生成CTFramesetterRef
    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attributed);
    
    CTFrameRef ctFrame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, attributed.length), path, NULL);
    
    // 6.繪製除圖片之外的部分
    CTFrameDraw(ctFrame, contextRef);
    
    
    // 7.內存管理,ARC不能管理CF開頭的對象,須要咱們本身手動釋放內存
    CFRelease(path);
    CFRelease(framesetter);
    CFRelease(ctFrame);
    
}
在整個繪製過程當中,NSMutableAttributedString是最重要的,給字符串設定不一樣的字體大小,顏色,乃至行距都是靠它,包括後面用空白佔位符來給圖片佔位,也依然是依賴該字符串。
相關文章
相關標籤/搜索