iOS中CoreText的学习记录(2)

NSString *str = @"This is a test of characterAttribute. 中文字符";
    
    NSMutableAttributedString *mabstring = [[NSMutableAttributedString alloc]initWithString:str];
    
    [mabstring beginEditing];

//some code

[mabstring endEditing];
    
    //CTFramesetter是CTFrame的创建工厂,NSAttributedString需要通过CTFrame绘制到界面上,得到CTFramesetter后,创建path(绘制路径),然后得到CTFrame,最后通过CTFrameDraw方法绘制到界面上
    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)mabstring);
    
    CGMutablePathRef Path = CGPathCreateMutable();
    
    CGPathAddRect(Path, NULL ,CGRectMake(10 , -20 ,self.bounds.size.width-10 , self.bounds.size.height-10));
    
    CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), Path, NULL);
    
    
    
    //获取当前(View)上下文以便于之后的绘画,这个是一个离屏。
    CGContextRef context = UIGraphicsGetCurrentContext();
    //    调整坐标系,防止文字倒立。
    CGContextSetTextMatrix(context , CGAffineTransformIdentity);
    
    //压栈,压入图形状态栈中.每个图形上下文维护一个图形状态栈,并不是所有的当前绘画环境的图形状态的元素都被保存。图形状态中不考虑当前路径,所以不保存
    //保存现在得上下文图形状态。不管后续对context上绘制什么都不会影响真正得屏幕。
    CGContextSaveGState(context);  

    //x,y轴方向移动
    CGContextTranslateCTM(context , 0 ,self.bounds.size.height);  
   
    //缩放x,y轴方向缩放,-1.0为反向1.0倍,坐标系转换,沿x轴翻转180度
    CGContextScaleCTM(context, 1.0 ,-1.0);  
    
    CTFrameDraw(frame,context);
    
    CGPathRelease(Path);  
    
    CFRelease(framesetter);


定制text



//设置字体间隔
    //const CFStringRef kCTKernAttributeName;//字符间隔属性,必须是CFNumberRef对象
    
    //设置字体间隔
    long number = 10;
    
    CFNumberRef num = CFNumberCreate(kCFAllocatorDefault,kCFNumberSInt8Type,&number);
    
    [mabstring addAttribute:(id)kCTKernAttributeName value:(__bridge id)num range:NSMakeRange(0, 5)];
    
    
    
     
     //设置字体属性 Georgia
    //const CFStringRef kCTFontAttributeName;//字体 CTFont  Default is Helvetica 12. 与UIFont的默认值不同
     CTFontRef font = CTFontCreateWithName(CFSTR("Zapfino"), 40, NULL);
     
     [mabstring addAttribute:(id)kCTFontAttributeName value:(__bridge id)font range:NSMakeRange(0, 4)];
    
    
     //设置字体颜色 kCTForegroundColorAttributeName
     [mabstring addAttribute:(id)kCTForegroundColorAttributeName value:(id)[UIColor yellowColor].CGColor range:NSMakeRange(0, 9)];

     //设置字体颜色为前影色
     
     CFBooleanRef flag = kCFBooleanTrue;
     [mabstring addAttribute:(id)kCTForegroundColorFromContextAttributeName value:(__bridge id)flag range:NSMakeRange(5, 10)];
    
     //设置空心字
     number = 2;
     CFNumberRef num2 = CFNumberCreate(kCFAllocatorDefault,kCFNumberSInt8Type,&number);
     
     [mabstring addAttribute:(id)kCTStrokeWidthAttributeName value:(__bridge id)num2 range:NSMakeRange(0, [str length])];

     //设置空心字颜色
     
     [mabstring addAttribute:(id)kCTStrokeColorAttributeName value:(id)[UIColor greenColor].CGColor range:NSMakeRange(0, [str length])];
   
    
    
     //设置斜体字
     
     CTFontRef font1 = CTFontCreateWithName((CFStringRef)[UIFont italicSystemFontOfSize:20].fontName, 14, NULL);
     
     [mabstring addAttribute:(id)kCTFontAttributeName value:(__bridge id)font1 range:NSMakeRange(0, 4)];
    

     //下划线
     
     [mabstring addAttribute:(id)kCTUnderlineStyleAttributeName value:(id)[NSNumber numberWithInt:kCTUnderlineStyleDouble] range:NSMakeRange(0, 4)];
     
     //下划线颜色
     
     [mabstring addAttribute:(id)kCTUnderlineColorAttributeName value:(id)[UIColor redColor].CGColor range:NSMakeRange(0, 4)];


同时设置多个属性

    //对同一段字体进行多属性设置
    
    //红色
    NSMutableDictionary *attributesDict = [NSMutableDictionary dictionaryWithObject:(id)[UIColor redColor].CGColor forKey:(id)kCTForegroundColorAttributeName];
    
    //斜体
    //创建字体以及字体大小
    CTFontRef font = CTFontCreateWithName((CFStringRef)[UIFont italicSystemFontOfSize:20].fontName, 40, NULL);
    
    [attributesDict setObject:(__bridge id)font forKey:(id)kCTFontAttributeName];
    
    //下划线
    [attributesDict setObject:(id)[NSNumber numberWithInt:kCTUnderlineStyleDouble] forKey:(id)kCTUnderlineStyleAttributeName];
    
    //空心字
    long number = 5;
    CFNumberRef num2 = CFNumberCreate(kCFAllocatorDefault,kCFNumberSInt8Type,&number);
    [attributesDict setObject:(__bridge id)num2 forKey:(id)kCTStrokeWidthAttributeName];
    
    
    [mabstring addAttributes:attributesDict range:NSMakeRange(0, 4)];


添加段落属性



//段落
    //line break
    CTParagraphStyleSetting lineBreakMode;
    CTLineBreakMode lineBreak = kCTLineBreakByCharWrapping; //换行模式
    lineBreakMode.spec = kCTParagraphStyleSpecifierLineBreakMode;
    lineBreakMode.value = &lineBreak;
    lineBreakMode.valueSize = sizeof(CTLineBreakMode);
    
    //行间距
    CTParagraphStyleSetting LineSpacing;
    CGFloat spacing = 40.0;  //指定间距
    LineSpacing.spec = kCTParagraphStyleSpecifierLineSpacingAdjustment;
    LineSpacing.value = &spacing;
    LineSpacing.valueSize = sizeof(CGFloat);
    
    CTParagraphStyleSetting settings[] = {lineBreakMode,LineSpacing};
    CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate(settings, 2);   //第二个参数为settings的长度
    [mabstring addAttribute:(NSString *)kCTParagraphStyleAttributeName
                             value:(__bridge id)paragraphStyle
                             range:NSMakeRange(0, mabstring.length)];



分列


// get current context and store it's state
    //创建图形上下文
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSaveGState(context);
    
    // translate CTM for iOS
    //重置位置
    CGContextTranslateCTM(context, 0, self.bounds.size.height);
    CGContextScaleCTM(context, 1, -1);
    
    // generate attributed string
    NSAttributedString *attrString = [[NSAttributedString alloc]initWithString:@"这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890,这是测试1234567890"];
    
    
    // Draw code start -------------------------------------------------------------------------------------------------
    CGRect bounds = CGRectInset(self.bounds, 25.0f, 25.0f);
    float columnWidth = (bounds.size.width - 30.0f) / 2.0f;
    float columnHeight = bounds.size.height;
    
    
    CTFramesetterRef framesetter
    = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)(attrString));
    int location = 0;
    
    // ------------- first column
    CGRect firstColumnRect = CGRectMake(bounds.origin.x, bounds.origin.y, columnWidth, columnHeight);
    CGMutablePathRef firstColumnPath = CGPathCreateMutable();
    CGPathAddRect(firstColumnPath, NULL, firstColumnRect);
    
    CTFrameRef firstColumnFrame =
    CTFramesetterCreateFrame(framesetter, CFRangeMake(location, 0), firstColumnPath, NULL);
    //计算指定frame绘制了多少字符
    CFRange firstColumnStringRange = CTFrameGetVisibleStringRange(firstColumnFrame);
    CTFrameDraw(firstColumnFrame, context);
    
    // recalculate the location for next frame.
    location = firstColumnStringRange.length;
    
    
    // ------------- second column
    CGRect secondColumnRect =
    CGRectMake(bounds.origin.x + 30 + columnWidth, bounds.origin.y, columnWidth, columnHeight);
    CGMutablePathRef secondColumnPath = CGPathCreateMutable();
    CGPathAddRect(secondColumnPath, NULL, secondColumnRect);
    
    CTFrameRef secondColumnFrame =
    CTFramesetterCreateFrame(framesetter,
                             CFRangeMake(location, 0),
                             secondColumnPath, NULL);
    CTFrameDraw(secondColumnFrame, context);
    
    // release
    CFRelease(firstColumnPath);
    CFRelease(firstColumnFrame);
    CFRelease(secondColumnPath);
    CFRelease(secondColumnFrame);
    CFRelease(framesetter);
    
    // Draw code end   -------------------------------------------------------------------------------------------------
    
    // restore current context
    CGContextRestoreGState(context);

段落样式



NSMutableAttributedString * mabstring = [[NSMutableAttributedString alloc]initWithString:src];
    
    long slen = [mabstring length];
    
    
    /*
     对齐属性:
     kCTLeftTextAlignment = 0,                //左对齐
     kCTRightTextAlignment = 1,               //右对齐
     kCTCenterTextAlignment = 2,              //居中对齐
     kCTJustifiedTextAlignment = 3,           //文本对齐
     kCTNaturalTextAlignment = 4              //自然文本对齐
     段落默认样式为
     kCTNaturalTextAlignment
     */
    
    //创建文本对齐方式
    CTTextAlignment alignment = kCTNaturalTextAlignment;//kCTNaturalTextAlignment;
    CTParagraphStyleSetting alignmentStyle;
    alignmentStyle.spec=kCTParagraphStyleSpecifierAlignment;//指定为对齐属性
    alignmentStyle.valueSize=sizeof(alignment);
    alignmentStyle.value=&alignment;
    
    
    //首行缩进
    CGFloat fristlineindent = 24.0f;
    CTParagraphStyleSetting fristline;
    fristline.spec = kCTParagraphStyleSpecifierFirstLineHeadIndent;
    fristline.value = &fristlineindent;
    fristline.valueSize = sizeof(float);
    
    //段缩进
    CGFloat headindent = 10.0f;
    CTParagraphStyleSetting head;
    head.spec = kCTParagraphStyleSpecifierHeadIndent;
    head.value = &headindent;
    head.valueSize = sizeof(float);
    
    //段尾缩进
    CGFloat tailindent = 50.0f;
    CTParagraphStyleSetting tail;
    tail.spec = kCTParagraphStyleSpecifierTailIndent;
    tail.value = &tailindent;
    tail.valueSize = sizeof(float);
    
//    //tab
//    CTTextAlignment tabalignment = kCTJustifiedTextAlignment;
//    CTTextTabRef texttab = CTTextTabCreate(tabalignment, 24, NULL);
//    CTParagraphStyleSetting tab;
//    tab.spec = kCTParagraphStyleSpecifierTabStops;
//    tab.value = &texttab;
//    tab.valueSize = sizeof(CTTextTabRef);
    //tab
    CTTextAlignment tabalignment = kCTJustifiedTextAlignment;
    CTTextTabRef texttab = CTTextTabCreate(tabalignment, 24, NULL);
    CTTextTabRef tabArray[] = {texttab};
    CFArrayRef tabStops = CFArrayCreate( kCFAllocatorDefault, (const void**) tabArray, 1, &kCFTypeArrayCallBacks );
    CFRelease(tabArray[0]);
    CTParagraphStyleSetting tab;
    tab.spec = kCTParagraphStyleSpecifierTabStops;
    tab.value = &tabStops;
    tab.valueSize = sizeof(CFArrayRef);
    
    
    /*
     换行模式:
     kCTLineBreakByWordWrapping = 0,        //出现在单词边界时起作用,如果该单词不在能在一行里显示时,整体换行。此为段的默认值。
     kCTLineBreakByCharWrapping = 1,        //当一行中最后一个位置的大小不能容纳一个字符时,才进行换行。
     kCTLineBreakByClipping = 2,            //超出画布边缘部份将被截除。
     kCTLineBreakByTruncatingHead = 3,      //截除前面部份,只保留后面一行的数据。前部份以...代替。
     kCTLineBreakByTruncatingTail = 4,      //截除后面部份,只保留前面一行的数据,后部份以...代替。
     kCTLineBreakByTruncatingMiddle = 5     //在一行中显示段文字的前面和后面文字,中间文字使用...代替。
     */
    
    //换行模式
    CTParagraphStyleSetting lineBreakMode;
    CTLineBreakMode lineBreak = kCTLineBreakByCharWrapping;//kCTLineBreakByWordWrapping;//换行模式
    lineBreakMode.spec = kCTParagraphStyleSpecifierLineBreakMode;
    lineBreakMode.value = &lineBreak;
    lineBreakMode.valueSize = sizeof(CTLineBreakMode);
    
    //多行高
    CGFloat MutiHeight = 2.0f;
    CTParagraphStyleSetting Muti;
    Muti.spec = kCTParagraphStyleSpecifierLineHeightMultiple;
    Muti.value = &MutiHeight;
    Muti.valueSize = sizeof(float);
    
    //最大行高
    CGFloat MaxHeight = 5.0f;
    CTParagraphStyleSetting Max;
    Max.spec = kCTParagraphStyleSpecifierLineHeightMultiple;
    Max.value = &MaxHeight;
    Max.valueSize = sizeof(float);
    
    //行距
    CGFloat _linespace = 5.0f;
    CTParagraphStyleSetting lineSpaceSetting;
    lineSpaceSetting.spec = kCTParagraphStyleSpecifierLineSpacing;
    lineSpaceSetting.value = &_linespace;
    lineSpaceSetting.valueSize = sizeof(float);
    
    //段前间隔
    CGFloat paragraphspace = 5.0f;
    CTParagraphStyleSetting paragraph;
    paragraph.spec = kCTParagraphStyleSpecifierLineSpacing;
    paragraph.value = ¶graphspace;
    paragraph.valueSize = sizeof(float);
    
    /*
     kCTWritingDirectionNatural = -1,            //普通书写方向,一般习惯是从左到右写
     kCTWritingDirectionLeftToRight = 0,         //从左到右写
     kCTWritingDirectionRightToLeft = 1          //从右到左写
     */
    
    //书写方向
    CTWritingDirection wd = kCTWritingDirectionRightToLeft;
    CTParagraphStyleSetting writedic;
    writedic.spec = kCTParagraphStyleSpecifierBaseWritingDirection;
    writedic.value = &wd;
    writedic.valueSize = sizeof(CTWritingDirection);
    
    //组合设置
    CTParagraphStyleSetting settings[] = {
//        alignmentStyle,
//        fristline,
//        head,
//        tail,
//        tab,
//        lineBreakMode,
//        Muti,
//        Max,
//        lineSpaceSetting,
        writedic
//        indentSetting,
        
        
    };
    
    //通过设置项产生段落样式对象
    CTParagraphStyleRef style = CTParagraphStyleCreate(settings, 11);
    
    // build attributes
    NSMutableDictionary *attributes = [NSMutableDictionary dictionaryWithObject:(__bridge id)style forKey:(id)kCTParagraphStyleAttributeName ];
    
    // set attributes to attributed string
    [mabstring addAttributes:attributes range:NSMakeRange(0, slen)];



参考文章: IOS CoreText.framework --- 基本用法 study-coretext IOS CoreText.framework --- 段落样子CTParagraphStyle


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值