美文网首页
CoreText Demo1 文本

CoreText Demo1 文本

作者: coder_feng | 来源:发表于2020-08-11 14:21 被阅读0次
    CoreText对文本和图片的绘制是依赖NSAttributedString属性字符串的,CoreText的绘制过程,可以通过下面的图片来了解 Layout Flow

    流程图的意思大概就是:获取context->翻转坐标系->创建属性NSAttributedString->根据NSAttributedString创建CTFramesetterRef->创建绘制区域CGPathRef->根据CTFramesetterRef和CGPathRef创建CTFrame->CTFrameDraw绘制

     CTFrame是指整个该UIView子控件的绘制区域,CTLine则是指每一行,CTRun则是每一段具有一样属性的字符串。比如某段字体大小、颜色都一致的字符串为一个CTRun,CTRun不可以跨行,不管属性一致或不一致。通常的结构是每一个CTFrame有多个CTLine,每一个CTLine有多个CTRun
    

    代码如下:

    - (void)drawRect:(CGRect)rect {
        // Drawing code
        [super drawRect:rect];
        //1.获取上下文
        CGContextRef contextRef = UIGraphicsGetCurrentContext();
        
        //[a,b,c,d,tx,ty]
        NSLog(@"转换前的坐标:%@",NSStringFromCGAffineTransform(CGContextGetCTM(contextRef)));
        //2.转换坐标系,CoreText的原点在左下角,UIKit原点在左上角
        CGContextSetTextMatrix(contextRef, CGAffineTransformIdentity);
        
        //3.这两种转换坐标的方式一样
    //    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:@"学习篮球羽毛球,可以笑的话,不会哭,可知道拿回孤独偏偏我没有遇上,无法港爱这个一种,遇上信服,你说加我邓毅要爆不从,是在无法港爱这一刻,你的刺青,请不要继续,以为山贼工行是"];
        [attributed addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:20] range:NSMakeRange(0, 5)];
        [attributed addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(6, attributed.length - 6)];
         [attributed addAttribute:(id)kCTForegroundColorAttributeName value:[UIColor greenColor] range:NSMakeRange(0, 5)];
        
        //设置行距等样式
        CGFloat lineSpace = 10;//行距一般取决于这个值
        CGFloat lineSpaceMax = 20;
        CGFloat lineSpaceMin = 2;
        const CFIndex kNumberOfSettings = 3;
        
        //结构体数组
        CTParagraphStyleSetting settings[kNumberOfSettings] = {
            {kCTParagraphStyleSpecifierLineSpacingAdjustment,sizeof(CGFloat),&lineSpace},
            {kCTParagraphStyleSpecifierMaximumLineSpacing,sizeof(CGFloat),&lineSpaceMax},
            {kCTParagraphStyleSpecifierMinimumLineSpacing,sizeof(CGFloat),&lineSpaceMin}
        };
        
        CTParagraphStyleRef paragraphRef = CTParagraphStyleCreate(settings, 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)(paragraphRef) range:NSMakeRange(0, attributed.length)];
        
        CFRelease(paragraphRef);
        
        //5.根据NSArrtibute
        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);
    
    }
    
    效果图 Snip20200810_5.png

    相关文章

      网友评论

          本文标题:CoreText Demo1 文本

          本文链接:https://www.haomeiwen.com/subject/ddtsdktx.html