Генерация содержания PDF
Платформа UIKit обеспечивает ряд функций для генерации содержания PDF использование собственного кода для прорисовки. Эти функции позволяют Вам создать графический контекст, предназначающийся для файла PDF или объекта данных PDF. Можно тогда создать одну или более страниц PDF и вовлечь те страницы с помощью того же UIKit и Базовых подпрограмм рисования Графики, которые Вы используете при рисовании для экрана. То, когда Вы сделаны, с чем Вас оставляют, является версией PDF того, что Вы нарисовали.
Полный процесс получения подобен процессу для создания любого другого изображения (описанный в Рисовании и Создании Изображений). Это состоит из следующих шагов:
Создайте контекст PDF и продвиньте его на графический штабель (как описано в Создании и Конфигурировании Контекста PDF).
Создайте страницу (как описано в Рисовании Страниц PDF).
Используйте UIKit или Базовые Графические подпрограммы для рисования содержания страницы.
Добавьте ссылки в случае необходимости (как описано в Создании Ссылок В Вашем Содержании PDF).
Повторите шаги 2, 3, и 4 по мере необходимости.
Закончите контекст PDF (как описано в Создании и Конфигурировании Контекста PDF) для сования контекста от графического штабеля и, в зависимости от того, как контекст создавался, или запишите получающиеся данные в указанный файл PDF или сохраните его в указанное
NSMutableData
объект.
Следующие разделы описывают процесс создания PDF более подробно с помощью простого примера. Для получения информации о функциях Вы используете, чтобы создать содержание PDF, видеть Ссылку на функцию UIKit.
Создание и конфигурирование контекста PDF
Вы создаете контекст графики PDF с помощью любого UIGraphicsBeginPDFContextToData
или UIGraphicsBeginPDFContextToFile
функция. Эти функции создают графический контекст и связывают его с местом назначения для данных PDF. Для UIGraphicsBeginPDFContextToData
функция, место назначения NSMutableData
возразите, что Вы обеспечиваете. И для UIGraphicsBeginPDFContextToFile
функция, место назначения является файлом в корневом каталоге Вашего приложения.
Документы в формате PDF организуют свое содержание с помощью основанной на странице структуры. Эта структура налагает два ограничения на любое получение, которое Вы делаете:
Должна быть открытая страница перед выпуском любых команд рисования.
Необходимо указать размер каждой страницы.
Функции, которые Вы используете для создания контекста графики PDF, позволяют Вам указывать размер страницы по умолчанию, но они автоматически не открывают страницу. После создания Вашего контекста необходимо явно открыть новую страницу с помощью любого UIGraphicsBeginPDFPage
или UIGraphicsBeginPDFPageWithInfo
функция. И каждый раз, когда Вы хотите создать новую страницу, необходимо вызвать одну из этих функций снова для маркировки запуска новой страницы. UIGraphicsBeginPDFPage
функция создает страницу с помощью размера по умолчанию, в то время как UIGraphicsBeginPDFPageWithInfo
функция позволяет Вам настроить размер страницы и другие атрибуты страницы.
Когда Вы сделаны, таща, Вы закрываете контекст графики PDF путем вызова UIGraphicsEndPDFContext
. Эта функция закрывает последнюю страницу и пишет содержание PDF в файл или объект данных, который Вы указали во время создания. Эта функция также удаляет контекст PDF из графического штабеля контекста.
Перечисление 4-1 показывает цикл обработки, используемый приложением для создания файла PDF из текста в текстовом представлении. Кроме трех вызовов функции сконфигурировать и управлять контекстом PDF, большая часть кода связана с рисованием желаемого содержания. textView
задействованная переменная указывает на UITextView
объект, содержащий требуемый текст. Приложение использует Базовую текстовую платформу (и более в частности a CTFramesetterRef
тип данных) для обработки текстового расположения и управления на последовательных страницах. Реализации для пользовательского renderPageWithTextRange:andFramesetter:
и drawPageNumber:
методы показаны в Перечислении 4-2.
Перечисление 4-1 , Создающее новый файл PDF
- (IBAction)savePDFFile:(id)sender |
{ |
// Prepare the text using a Core Text Framesetter. |
CFAttributedStringRef currentText = CFAttributedStringCreate(NULL, (CFStringRef)textView.text, NULL); |
if (currentText) { |
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(currentText); |
if (framesetter) { |
NSString *pdfFileName = [self getPDFFileName]; |
// 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]; |
// 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); |
} else { |
NSLog(@"Could not create the framesetter needed to lay out the atrributed string."); |
} |
// Release the attributed string. |
CFRelease(currentText); |
} else { |
NSLog(@"Could not create the attributed string for the framesetter"); |
} |
} |
Рисование страниц PDF
Все получение PDF должно быть сделано в контексте страницы. Каждый документ в формате PDF имеет по крайней мере одну страницу, и у многих могут быть многократные страницы. Вы указываете запуск новой страницы путем вызова UIGraphicsBeginPDFPage
или UIGraphicsBeginPDFPageWithInfo
функция. Эти функции близко предыдущая страница (если Вы были открыты), создайте новую страницу и подготовьте ее к рисованию. UIGraphicsBeginPDFPage
создает новую страницу с помощью размера по умолчанию в то время как UIGraphicsBeginPDFPageWithInfo
функция позволяет Вам настроить размер страницы или настроить другие аспекты страницы PDF.
После создания страницы все последующие команды рисования получены контекстом графики PDF и переведены в команды PDF. Можно нарисовать что-либо, что Вы хотите на странице, включая текст, векторные формы и изображения, как Вы были бы в пользовательских представлениях своего приложения. Команды рисования, которые Вы выпускаете, получены контекстом PDF и переведены в данные PDF. Размещение содержания на страница полностью ваше дело, но должна иметь место в ограничительном прямоугольнике страницы.
Перечисление 4-2 показывает, что два пользовательских метода раньше рисовали содержание в странице PDF. renderPageWithTextRange:andFramesetter:
метод использует Базовый текст для создания текстовой рамки, соответствующей странице, и затем разметьте некоторый текст в том кадре. После разметки текста это возвращает обновленный диапазон, отражающий конец текущей страницы и начало следующей страницы. drawPageNumber:
метод использует NSString
рисование возможностей нарисовать строку номера страницы у основания каждой страницы PDF.
Перечисление 4-2 , Получающее основанное на странице содержание
// Use Core Text to draw the text in a frame on the page. |
- (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; |
} |
- (void)drawPageNumber:(NSInteger)pageNum |
{ |
NSString *pageString = [NSString stringWithFormat:@"Page %d", pageNum]; |
UIFont *theFont = [UIFont systemFontOfSize:12]; |
CGSize maxSize = CGSizeMake(612, 72); |
CGSize pageStringSize = [pageString sizeWithFont:theFont |
constrainedToSize:maxSize |
lineBreakMode:UILineBreakModeClip]; |
CGRect stringRect = CGRectMake(((612.0 - pageStringSize.width) / 2.0), |
720.0 + ((72.0 - pageStringSize.height) / 2.0), |
pageStringSize.width, |
pageStringSize.height); |
[pageString drawInRect:stringRect withFont:theFont]; |
} |
Создание ссылок в содержании PDF
Помимо рисования содержания, можно также включать ссылки, берущие пользователя к другой странице в том же файле PDF или к внешнему URL. Для создания единственной ссылки необходимо добавить исходный прямоугольник и место назначения ссылки к страницам PDF. Один из атрибутов места назначения ссылки является строкой, служащей уникальным идентификатором для той ссылки. Для создания ссылки к определенному месту назначения Вы указываете уникальный идентификатор для того места назначения при создании исходного прямоугольника.
Для добавления нового места назначения ссылки к содержанию PDF Вы используете UIGraphicsAddPDFContextDestinationAtPoint
функция. Эта функция связывает указанное место назначения с отдельным моментом на текущей странице. Когда Вы хотите соединиться с тем пунктом назначения, Вы используете UIGraphicsSetPDFContextDestinationForRect
функция для указания исходного прямоугольника для ссылки. Рисунок 4-1 показывает отношение между этими двумя вызовами функции, когда применено к страницы Ваших документов в формате PDF. Ответвление на прямоугольнике, окружающем “, видит, что Глава 1” текст берет пользователя к соответствующему пункту назначения, расположенному наверху Главы 1.
В дополнение к созданию ссылок в документе можно также использовать UIGraphicsSetPDFContextURLForRect
функция для создания ссылок к содержанию расположилась за пределами документа. При использовании этой функции для создания ссылок Вы указываете целевой URL и исходный прямоугольник на текущей странице.