1

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

即:我想用普通字体绘制'xyz()'部分,用斜体绘制' abc '。

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

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

无法获取属性的键,我该怎么办?

无论如何在这里使用 NSAttributedString 吗?

4

3 回答 3

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 字符串的范围。您可以使用正则表达式或只是一般的字符串搜索来找到它。

IE

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);
}

希望能帮助到你。

于 2012-05-04T14:11:42.417 回答
0

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

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

于 2012-05-04T13:49:28.640 回答
0

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

于 2012-05-04T13:58:58.347 回答