当我尝试绘制NSAttributedString并在iOS5模拟器中运行时,我遇到了崩溃。在iOS6中它运行良好。我不明白我做错了什么,因为从我读到的我的代码也应该适用于iOS5。我的设置:
我运行以下代码:
- (void)drawRect:(CGRect)rect
{
NSDictionary *txtAttr = @{
(NSString *)kCTFontAttributeName : [UIFont boldSystemFontOfSize:16]
};
NSMutableAttributedString * string = [[NSMutableAttributedString alloc] initWithString:@"foobar" attributes:txtAttr];
CGContextRef ctx = UIGraphicsGetCurrentContext();
// flip context
CGContextSaveGState(ctx);
CGContextTranslateCTM(ctx, 0, self.bounds.size.height);
CGContextScaleCTM(ctx, 1, -1);
// I get a crash on the line below
CTLineRef line = CTLineCreateWithAttributedString(
(__bridge CFAttributedStringRef)string
);
CGContextSetTextPosition(ctx, 0, 4);
CTLineDraw(line, ctx);
CFRelease(line);
CGContextRestoreGState(ctx);
}
这会在CTLineCreateWithAttributedString
上与堆栈跟踪崩溃:
#0 0x00140c68 in TAttributes::TAttributes(__CFDictionary const*) ()
#1 0x0011c499 in TTypesetterAttrString::Initialize(__CFAttributedString const*) ()
#2 0x0011c313 in TTypesetterAttrString::TTypesetterAttrString(__CFAttributedString const*) ()
#3 0x0010db14 in CTLineCreateWithAttributedString ()
#4 0x00065e5f in -[AttributedLabel drawRect:] at AttributedLabel.m:77
#5 0x003c8bd3 in -[UIView(CALayerDelegate) drawLayer:inContext:] ()
#6 0x002a7963 in -[CALayer drawInContext:] ()
#7 0x002b9f80 in backing_callback(CGContext*, void*) ()
#8 0x001d83fd in CABackingStoreUpdate_ ()
#9 0x002b9e2e in CA::Layer::display_() ()
#10 0x002a7a3d in -[CALayer _display] ()
#11 0x002adfd5 in CA::Layer::display() ()
#12 0x002a7a63 in -[CALayer display] ()
#13 0x002b19ae in CA::Layer::display_if_needed(CA::Transaction*) ()
#14 0x00236509 in CA::Context::commit_transaction(CA::Transaction*) ()
#15 0x002383f6 in CA::Transaction::commit() ()
#16 0x00237ad0 in CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) ()
#17 0x0140c99e in __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ ()
#18 0x013a3640 in __CFRunLoopDoObservers ()
#19 0x0136f4c6 in __CFRunLoopRun ()
#20 0x0136ed84 in CFRunLoopRunSpecific ()
#21 0x0136ec9b in CFRunLoopRunInMode ()
#22 0x018157d8 in GSEventRunModal ()
#23 0x0181588a in GSEventRun ()
#24 0x0038a626 in UIApplicationMain ()
发生崩溃的地方如下所示:
0x140c5a: calll 0x11c812 ; TCFRetained<__CFDictionary const*>::Retain(__CFDictionary const*)
0x140c5f: movl 8(%ebp), %eax
0x140c62: movl 4(%eax), %eax
0x140c65: movl 20(%eax), %eax
0x140c68: movl 8(%eax), %eax ;I get a Thread 1: EXC_BAD_ACCESS (code=2, address=0x08) here
0x140c6b: testl %eax, %eax
0x140c6d: je 0x140d0c ; TAttributes::TAttributes(__CFDictionary const*) + 482
答案 0 :(得分:3)
错误是使用UIFont
。 iOS5需要CTFont
,这是Core Foundation类型。下面是我用来使其工作的代码:
CTFontRef font = CTFontCreateWithName((CFStringRef)@"HelveticaNeue-Bold", 16, NULL);
NSDictionary *txtAttr = @{
(NSString *)kCTFontAttributeName : (id)CFBridgingRelease(font)
};
使用您的字体书应用程序找到字体并使用PostScript名称。如果我没有读过:NSAttributedString in CATextLayer causes EXC_BAD_ACCESS (ios 5.0)
,我就不会想到这一点答案 1 :(得分:2)
我不知道你是否想逐行绘制文本,但这是我用来在自定义UIView上绘制NSAttributedString的代码: 我根据您的属性字符串更改了代码:
- (void)drawRect:(CGRect)rect {
NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:@"yourString"];
UIFont *font = [UIFont boldSystemFontOfSize:16];
CTFontRef fontR = CTFontCreateWithName((CFStringRef)font.fontName, font.pointSize, NULL);
[attrString addAttribute:(NSString*)kCTFontAttributeName
value:(id)fontR
range:NSMakeRange(0, [yourText length])];
CFRelease(fontR);
CGMutablePathRef path = CGPathCreateMutable();
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attrString);
// added 3 pixels at the top of the frame so that the text is not cuted
CGRect newRect = CGRectMake(rect.origin.x, rect.origin.y - 3, rect.size.width, rect.size.height);
CGPathAddRect(path, NULL, newRect);
CTFrameRef frameRef = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);
CFRelease(framesetter);
CGPathRelease(path);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
CGContextTranslateCTM(context, 0, self.bounds.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CTFrameDraw(frameRef, context);
CFRelease(frameRef);
[super drawRect:newRect];
}
我希望我没有忘记任何事情,因为我还对属性文本进行了一些计算,并将其删除以获得更好的示例。
希望这会有所帮助;)