zoukankan      html  css  js  c++  java
  • 关于图文混排的的框架coreText

    (1) NSAttributedString

          NSAttributedString 可以将一段文字中的部分文字设置单独的字体和颜色。

          与UITouch结合可以实现点击不同文字触发不同事件的交互功能。

           主要方法:

               - (void)addAttribute:(NSString *)name value:(id)value range:(NSRange)range;

               可以设置某段文字的字体名称,颜色,下滑线等信息。

               - (void)removeAttribute:(NSString *)name range:(NSRange)range;

               移除之前设置的字体属性值。

               - (void)addAttributes:(NSDictionary *)attrs range:(NSRange)range;

               存储某段文字包含的信息(包括字体属性或其它,也可以存储一些自定义的信息)

               - (NSDictionary *)attributesAtIndex:(NSUInteger)location effectiveRange:(NSRangePointer)range;

               通过location来获取某段文字中之前存储的信息NSDictionary

       //设置字体
       CTFontRef aFont = CTFontCreateWithName((CFStringRef)textFont.fontName, textFont.pointSize, NULL);
       if (!aFont) return;
       CTFontRef newFont = CTFontCreateCopyWithSymbolicTraits(aFont, 0.0, NULL, kCTFontItalicTrait, kCTFontBoldTrait);    //将默认黑体字设置为其它字体
       [self removeAttribute:(NSString*)kCTFontAttributeName range:textRange];
       [self addAttribute:(NSString*)kCTFontAttributeName value:(id)newFont range:textRange];
       CFRelease(aFont);
       CFRelease(newFont);
       
       //设置字体颜色
       [self removeAttribute:(NSString*)kCTForegroundColorAttributeName range:textRange];
       [self addAttribute:(NSString*)kCTForegroundColorAttributeName value:(id)textColor.CGColor range:textRange];
       
       //设置对齐 换行
       CTTextAlignment coreTextAlign = kCTLeftTextAlignment;
       CTLineBreakMode coreTextLBMode = kCTLineBreakByCharWrapping;
       CTParagraphStyleSetting paraStyles[2] =
       {
           {.spec = kCTParagraphStyleSpecifierAlignment, .valueSize = sizeof(CTTextAlignment), .value = (const void*)&coreTextAlign},
           {.spec = kCTParagraphStyleSpecifierLineBreakMode, .valueSize = sizeof(CTLineBreakMode), .value = (const void*)&coreTextLBMode},
       };
       CTParagraphStyleRef aStyle = CTParagraphStyleCreate(paraStyles, 2);
       [self removeAttribute:(NSString*)kCTParagraphStyleAttributeName range:textRange];
       [self addAttribute:(NSString*)kCTParagraphStyleAttributeName value:(id)aStyle range:textRange];
       CFRelease(aStyle);

    (2)Draw NSAttributedString


           
       CGContextRef cgc = UIGraphicsGetCurrentContext();
       CGContextSaveGState(cgc);
       
       //图像方向转换
       CGContextConcatCTM(cgc, CGAffineTransformScale(CGAffineTransformMakeTranslation(0, self.bounds.size.height), 1.f, -1.f));
       
       CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)weiBoText);
       drawingRect = self.bounds;
       CGMutablePathRef path = CGPathCreateMutable();
       CGPathAddRect(path, NULL, drawingRect);
       textFrame = CTFramesetterCreateFrame(framesetter,CFRangeMake(0,0), path, NULL);
       CGPathRelease(path);
       CFRelease(framesetter);
       
       CTFrameDraw(textFrame, cgc);
       CGContextRestoreGState(cgc);

    (3)图文混排

         CTFrameRef  textFrame     // coreText 的 frame

         CTLineRef      line             //  coreText 的 line

         CTRunRef      run             //  line  中的部分文字

         相关方法:

       
       CFArrayRef CTFrameGetLines    (CTFrameRef frame )      //获取包含CTLineRef的数组

       void CTFrameGetLineOrigins(
       CTFrameRef frame,
       CFRange range,
       CGPoint origins[] )  //获取所有CTLineRef的原点

     CFRange CTLineGetStringRange  (CTLineRef line )    //获取line中文字在整段文字中的Range

     CFArrayRef CTLineGetGlyphRuns  (CTLineRef line )    //获取line中包含所有run的数组

     CFRange CTRunGetStringRange  (CTRunRef run )     //获取run在整段文字中的Range

     CFIndex CTLineGetStringIndexForPosition(
       CTLineRef line,
       CGPoint position )   //获取点击处position文字在整段文字中的index

       CGFloat CTLineGetOffsetForStringIndex(
       CTLineRef line,
       CFIndex charIndex,
       CGFloat* secondaryOffset ) //获取整段文字中charIndex位置的字符相对line的原点的x值

      主要步骤:

           1)计算并存储文字中保含的所有表情文字及其Range

           2)替换表情文字为指定宽度的NSAttributedString

               CTRunDelegateCallbacks callbacks;
       callbacks.version = kCTRunDelegateVersion1;
       callbacks.getAscent = ascentCallback;
       callbacks.getDescent = descentCallback;
       callbacks.getWidth = widthCallback;
       callbacks.dealloc = deallocCallback;
       
       CTRunDelegateRef runDelegate = CTRunDelegateCreate(&callbacks, NULL);
       NSDictionary *attrDictionaryDelegate = [NSDictionary dictionaryWithObjectsAndKeys:
                                               (id)runDelegate, (NSString*)kCTRunDelegateAttributeName,
                                               [UIColor clearColor].CGColor,(NSString*)kCTForegroundColorAttributeName,
                                               nil];
       
       NSAttributedString *faceAttributedString = [[NSAttributedString alloc] initWithString:@"*" attributes:attrDictionaryDelegate];
       
       [weiBoText replaceCharactersInRange:faceRange withAttributedString:faceAttributedString];
       [faceAttributedString release];    

           3)  根据保存的表情文字的Range计算表情图片的Frame

                    textFrame 通过CTFrameGetLines 获取所有line的数组 lineArray

                   遍历lineArray中的line通过CTLineGetGlyphRuns获取line中包含run的数组 runArray

                   遍历runArray中的run 通过CTRunGetStringRange获取run的Range

                   判断表情文字的location是否在run的Range

                   如果在 通过CTLineGetOffsetForStringIndex获取x的值 y的值为line原点的值

           4)Draw表情图片到计算获取到的Frame

    (3)点击文字触发事件

      

      主要步骤:

           1) 根据touch事件获取点point

           2)   textFrame 通过CTFrameGetLineOrigins获取所有line的原点

           3) 比较point和line原点的y值获取点击处于哪个line

           4)  line、point 通过CTLineGetStringIndexForPosition获取到点击字符在整段文字中的    index   

           5)  NSAttributedString 通过index 用方法-(NSDictionary *)attributesAtIndex:(NSUInteger)location effectiveRange:(NSRangePointer)range  可以获取到点击到的NSAttributedString中存储的NSDictionary

           6) 通过NSDictionary中存储的信息判断点击的哪种文字类型分别处理

    转自http://ios-iphone.diandian.com/post/2012-03-06/15104770

    确实是一个比较详细的总结了。以前开发中没用这个,用其他的虽然用其他的办法也能实现,但是麻烦了许多,浪费了许多时间

  • 相关阅读:
    OpenCV 图像二值化 threshold
    C++ pow()函数
    Marr-Hildreth 边缘检测 OpenCV C++实现
    OpenCV 边缘检测 Canny
    OpenCV Canny()函数
    OpenCV Sobel()函数
    OpenCV 边缘检测 Sobel
    OpenCV 边缘检测 Laplacian
    OpenCV 边缘检测 Scharr
    OpenCV 形态学变换 morphologyEx函数
  • 原文地址:https://www.cnblogs.com/lingzhiguiji/p/3578589.html
Copyright © 2011-2022 走看看