【问题标题】:Drawing one NSString with two different fonts in drawRect?在drawRect中用两种不同的字体绘制一个NSString?
【发布时间】:2012-05-04 22:16:56
【问题描述】:

我有一个字符串作为实例变量,我想用两种不同的字体部分地绘制它。 具体来说,它是:xyz(abc)。

ie:我想用普通字体绘制“xyz()”部分,用斜体绘制“abc”。

这个字符串是一个属性,视图是通用的。只有在特定情况下才应该显示这样的字符串。

我尝试了 NSAttributedString 及其可变版本,但它似乎在 iOS 上不完全支持。

无法获取属性的键,我应该如何处理?

这里有没有办法使用 NSAttributedString ?

【问题讨论】:

    标签: ios nsattributedstring


    【解决方案1】:

    我会将 UIView 子类化以使用核心文本进行绘制,并将自定义的 NSAttributed 字符串传递给它,

    在我的头顶上是这样的:

    CustomLabel.h
    #import <CoreText/CoreText.h>
    
    @interface CustomLabel : UIView
    @property NSAttributedString *attributedText;
    @end
    
    CustomLabel.m
    
    @interface SMAttributedTextView ()
    {
        @protected
        CTFramesetterRef _framesetter;
    }
    
    @implementation SMAttributedTextView
    
    @synthesize attributedString = _attributedString;
        //need dealloc even with ARC method to release framesetter if it still exists
    - (void)dealloc{
        if (_framesetter) CFRelease(_framesetter);
    }
    
    - (void)setAttributedString:(NSAttributedString *)aString
    {
        _attributedString = aString;
        [self setNeedsDisplay];//force redraw
    }
    
    - (void)drawRect:(CGRect)rect
    {
        CGContextRef context = UIGraphicsGetCurrentContext();
    
        //Context Drawing Setup
        CGContextSetTextMatrix(context, CGAffineTransformIdentity);
        CGContextTranslateCTM(context, 0, self.frame.size.height);
        CGContextScaleCTM(context, 1.0, -1.0);
        CGContextSetShouldSubpixelPositionFonts(context, YES);
        CGContextSetShouldSubpixelQuantizeFonts(context, YES);
        CGContextSetShouldAntialias(context, YES);
    
        CGMutablePathRef path = CGPathCreateMutable();
        CGPathAddRect(path, NULL, rect);
    
        CTFramesetterRef framesetter = [self framesetter];
        CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, [_attributedText length]), path, NULL);
        CTFrameDraw(frame, context);
        CFRelease(frame);
        CFRelease(path);
    
        UIGraphicsPushContext(context);
    }
    
    @end
    

    所以在此之外,您将调用属性字符串的设置器,它应该重绘。 在将其发送到视图之前,您还可以将自定义特征应用于 NSAttributd 字符串的范围。您可以使用正则表达式或只是一般的字符串搜索来找到它。

    NSMutableAttributedString *aString = [[NSMutableAttributedString alloc] initWithString:@"xyz(abc)"];
    NSRange rangeOfABC = NSMakeRange(4,3);
    //make style dictionary **see core text docs - I can't remeber off the top of my head sorry
    [aString addAttributes:newAttrs range:rangeOfABC];
    
    [customlabel setAttributedString:aString];
    

    代码方面可能略有不同 - 我在我的非工作机器上抱歉,所以无法 100% 验证它,

    同样根据记忆,这是如何将斜体特征应用于属性字符串的当前字体

    NSString *targetString = @"xyc(abc)";
    NSMutableAttributedString *attString = [[NSMutableAttributedString alloc] initWithString:targetString];
    NSRange entireRange = NSMakeRange(0, (targetString.length -1));
    NSDictionary *attDict = [attString attributesAtIndex:entireRange.location effectiveRange:&entireRange];
    CTFontRef curFontRef = (__bridge CTFontRef)[attDict objectForKey:@"NSFont"];
    CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(curFontRef);
    BOOL isItalic = ((traits & kCTFontItalicTrait) == kCTFontItalicTrait);
    
    NSMutableDictionary *newAttrs = [NSMutableDictionary dictionary];
    CTFontRef italicRef = CTFontCreateCopyWithSymbolicTraits(curFontRef,
                                                             CTFontGetSize(curFontRef),
                                                             NULL,
                                                             kCTFontItalicTrait,
                                                             kCTFontItalicTrait);
    
    if (italicRef)
    {
        newAttrs = [NSDictionary dictionaryWithObjectsAndKeys:(__bridge id)italicRef, kCTFontAttributeName,nil];
        [attString addAttributes:newAttrs range:NSMakeRange(4,3)];//or whatever range you want
        CFRelease(italicRef);
    }
    

    希望对你有帮助。

    【讨论】:

      【解决方案2】:

      我认为你需要使用两个不同的字符串/标签来达到这个效果。 据我所知,仅使用标签或其他类似元素是不可能的。

      我也在类似的情况下使用了webviews,并使用html/css来显示不同样式的文本的一部分。

      【讨论】:

        【解决方案3】:

        您必须提供自己的控件来绘制NSAttributedString,例如TTTAttributedLabel

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-12-31
          • 2016-01-11
          • 1970-01-01
          • 2013-09-02
          • 2016-05-11
          • 1970-01-01
          • 1970-01-01
          • 2013-02-07
          相关资源
          最近更新 更多