我有一个应用程序,从iOS 4开始就一直在使用quartz/UIKit生成PDF,但自从将项目升级到iOS 8后,每当它试图将文本渲染到PDF上下文中时,就会崩溃。绘制线条和矩形是很好的,但是字符串呈现的任何排列都会失败,并在一个低级库中出现异常。
我没有发布我自己的源代码,而是试着从Apple的文档中反向操作。诚然,它已经过时了,但如果它不再起作用,他们应该修复它。
改编源代码:
- (void)producePDF
{
NSString *text=@"Bzorg blarf gloop foo!";
CFAttributedStringRef currentText = CFAttributedStringCreate(NULL, (CFStringRef)text, NULL);
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(currentText);
NSString *pdfFileName = fullPath;
// Create the PDF context using the default page size of 612 x 792.
UIGraphicsBeginPDFContextToFile(pdfFileName, CGRectZero, nil);
CFRange currentRange = CFRangeMake(0, 0);
NSInteger currentPage = 0;
BOOL done = NO;
do {
// Mark the beginning of a new page.
UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, 612, 792), nil);
// Draw a page number at the bottom of each page.
currentPage++;
//[self drawPageNumber:currentPage];
// Render the current page and update the current range to
// point to the beginning of the next page.
//currentRange = [self renderPageWithTextRange:currentRange andFramesetter:framesetter];
currentRange=[self renderPage:currentPage withTextRange:currentRange andFramesetter:framesetter];
// If we're at the end of the text, exit the loop.
if (currentRange.location == CFAttributedStringGetLength((CFAttributedStringRef)currentText))
done = YES;
} while (!done);
// Close the PDF context and write the contents out.
UIGraphicsEndPDFContext();
// Release the framewetter.
CFRelease(framesetter);
// Release the attributed string.
CFRelease(currentText);
}
- (CFRange)renderPage:(NSInteger)pageNum withTextRange:(CFRange)currentRange
andFramesetter:(CTFramesetterRef)framesetter
{
// Get the graphics context.
CGContextRef currentContext = UIGraphicsGetCurrentContext();
// Put the text matrix into a known state. This ensures
// that no old scaling factors are left in place.
CGContextSetTextMatrix(currentContext, CGAffineTransformIdentity);
// Create a path object to enclose the text. Use 72 point
// margins all around the text.
CGRect frameRect = CGRectMake(72, 72, 468, 648);
CGMutablePathRef framePath = CGPathCreateMutable();
CGPathAddRect(framePath, NULL, frameRect);
// Get the frame that will do the rendering.
// The currentRange variable specifies only the starting point. The framesetter
// lays out as much text as will fit into the frame.
CTFrameRef frameRef = CTFramesetterCreateFrame(framesetter, currentRange, framePath, NULL);
CGPathRelease(framePath);
// Core Text draws from the bottom-left corner up, so flip
// the current transform prior to drawing.
CGContextTranslateCTM(currentContext, 0, 792);
CGContextScaleCTM(currentContext, 1.0, -1.0);
// Draw the frame.
CTFrameDraw(frameRef, currentContext);
// Update the current range based on what was drawn.
currentRange = CTFrameGetVisibleStringRange(frameRef);
currentRange.location += currentRange.length;
currentRange.length = 0;
CFRelease(frameRef);
return currentRange;
}
我尝试过许多排列,它们似乎都在呈现文本时失败。上面的Apple派生的示例在这一行中消失了:
CTFrameDraw(frameRef, currentContext);
其他代码试图获得最低限度的工作:
NSMutableParagraphStyle* textStyle = NSMutableParagraphStyle.defaultParagraphStyle.mutableCopy;
textStyle.alignment = NSTextAlignmentLeft;
NSDictionary* textFontAttributes = @{
NSFontAttributeName: [UIFont fontWithName: @"Helvetica" size: 12], NSForegroundColorAttributeName: UIColor.redColor,
NSParagraphStyleAttributeName: textStyle};
[@"Hello, World!" drawAtPoint:CGPointZero withAttributes:textFontAttributes];
..。在"drawAtPoint“调用时崩溃。
发布于 2014-11-11 11:39:14
无论如何,如果我在没有附加调试器的设备上执行应用程序(例如,从springboard运行/终止/启动),PDF创建就可以正常工作。可能在现实生活中抛出的任何虚假异常都会被忽略。
https://stackoverflow.com/questions/26742235
复制相似问题