Печать из приложения
NSPrintOperation
возразите управляет процессом, создающим рабочее место печати. Задания печати обычно отправляются в принтер, но они могут также использоваться для генерации данных Portable Document Format (PDF) для приложения. NSPrintOperation
возразите управляет полным процессом, полагаясь NSView
объект генерировать фактический код. После того, как создаваемый, работа печати может быть сконфигурирована несколькими способами.
В Приложении Какао существует два класса, обеспечивающие инфраструктуру для обработки печати:
NSView
NSDocument
Методы Ваше использование приложения для обработки печати зависит, на котором классе она использует для его содержания.
Печать в приложении, использующем NSView
Печать в приложениях, которые не являются основанными на документе работами лучше всего для приложений, имеющих только одно печатаемое представление (т.е. NSView
объект) в его главном окне, которое может быть первым респондентом. Например, в простом текстовом редакторе, только представление, содержащее текстовый документ, может сфокусироваться, таким образом, это прямо для реализации печати в текстовом представлении. Вы видите пример этой архитектуры в проекте примера кода TextEdit.
Когда Ваш пользовательский интерфейс содержит многократные представления, которые могут сфокусироваться, такой как многократные NSTextField
объекты, основанная на представлении печать не работает хорошо. Когда пользователь выбирает Команду печати, представление, получающее print:
обменивайтесь сообщениями распечатывает себя, но ничто иное. Если фокус находится в текстовом поле, например, только содержание того текстового поля распечатано. Это, вероятно, не желаемое поведение. Вместо этого Ваше приложение должно проявить более основанный на документе подход. Посмотрите Печать в Приложении Который Использование NSDocument.
В основанном на представлении приложении Ваше приложение получает a print:
обменивайтесь сообщениями, когда пользователь выберет Print из меню File. В Вашей реализации print:
метод, Вы создаете NSPrintOperation
объект, инициализированный с представлением для печати и, дополнительно, NSPrintInfo
объект, содержащий настройки печати.
Работа печати не запускается, пока Вы не вызываете один из runOperation
методы NSPrintOperation
как показано в Перечислении 3-1.
Перечисление 3-1 простая реализация печати: метод для основанного на представлении приложения
- (void)print:(id)sender { |
[[NSPrintOperation printOperationWithView:self] runOperation]; |
} |
Эта реализация print:
запускается путем создания NSPrintOperation
объект, управляющий процессом генерации надлежащего кода для устройства принтера. Когда выполнено, NSPrintOperation
объект создает и выводит на экран панель Print (который является NSPrintPanel
объект, создаваемый автоматически системой печати) для получения настроек печати от пользователя. Приложение совместно использовало NSPrintInfo
объект используется для начальных установок.
Печать в приложении, использующем NSDocument
Приложение, использующее NSDocument
класс для управления его документами получает дополнительную инфраструктуру для обработки печати документа. Поскольку настройки печати могут отличаться для различных документов, каждого экземпляра NSDocument
имеет его собственное NSPrintInfo
объект, к которому получают доступ с printInfo
и setPrintInfo:
методы.
В основанном на документе приложении, когда пользователь выбирает Print из меню File, система печати отправляет a printDocument:
сообщение, который только NSDocument
реализации класса. NSDocument
объект, связанный с главным окном приложения, получает сообщение и вызывает метод printDocumentWithSettings:showPrintPanel:delegate:didPrintSelector:contextInfo:
с YES
как параметр за showPrintPanel
.
Если Вы указываете для показа панели Print, метод представляет ее и распечатывает, только если пользователь утверждает панель. Метод добавляет NSPrintInfo
атрибуты, от printSettings
словарь, который Вы передаете к копии информации печати документа и получающимся информационным настройкам печати, используется для работы. Когда печать завершена или отменяется, метод отправляет сообщение, выбранное didPrintSelector
делегату, с contextInfo
как последний параметр. Метод выбран didPrintSelector
должен иметь ту же подпись как:
- (void)document:(NSDocument *)document didPrint:(BOOL)didPrintSuccessfully contextInfo: (void *)contextInfo; |
Реализация по умолчанию printDocumentWithSettings:showPrintPanel:delegate:didPrintSelector:contextInfo:
вызывает printOperationWithSettings:error:
. Необходимо переопределить этот метод, чтобы позволить распечатать в приложении; реализация по умолчанию повышает исключение.
Если printDocumentWithSettings:showPrintPanel:delegate:didPrintSelector:contextInfo:
возвраты nil
, это представляет ошибку пользователю прежде, чем передать делегата. Иначе это вызывает эту строку кода:
[thePrintOperation setShowsPrintPanel:showPrintPanel]; |
сопровождаемый этим кодом:
[self runModalPrintOperation:thePrintOperation |
delegate:delegate |
didRunSelector:didPrintSelector |
contextInfo:contextInfo]; |
Настройка содержания для печатной страницы, не дисплея
В некоторых случаях могло бы быть предпочтительно для Вашего приложения отправить содержание в принтер, который не идентичен нарисованному на экране. Например, в то время как печатные данные должны быть отформатированы как таблица, главное окно приложения базы данных могло бы содержать интерфейс для просмотра и редактирования базы данных. В этом случае для документа нужны отдельные представления для рисования в окне и для печати к принтеру. Если у Вас есть хороший проект Контроллера представления Модели, можно легко создать пользовательское представление, которое может нарисовать специфичную для принтера версию модели данных и использовать его при создании работы печати
У Вас есть две опции для настройки содержания для печатной страницы:
В drawRect Вашего приложения: метод, перейдите код как показано здесь:
- (void)drawRect:(NSRect)r {
if ( [NSGraphicsContext currentContextDrawingToScreen] ) {
// Draw screen-only elements here
} else {
// Draw printer-only elements here
}
// Draw common elements here
}
Создайте представление, которое это использовало только для печати.
Когда печать к представлению возражает, что Ваше приложение использует только для печати, Вы должны:
Создайте представление, которое будет использоваться только для печати, удостоверяясь, что Вы измеряете ее соответственно.
Создайте работу печати с помощью представления печати.
NSPrintOperation *printOp = [NSPrintOperation printOperationWithView:myPrintingView
printInfo:[self printInfo]];
Идеально, также укажите, что работа печати может работать в отдельном потоке. Это заставляет панель прогресса печати появляться как лист на окне документа.
[printOp setCanSpawnSeparateThread:YES];
Вы, возможно, также должны были бы скорректировать свое получение на основе атрибута в работе печати NSPrintInfo
объект. Можно получить текущую работу печати с NSPrintOperation
метод класса currentOperation
и затем получите NSPrintInfo
объект от printInfo
метод.
NSPrintOperation *op = [NSPrintOperation currentOperation]; |
NSPrintInfo *pInfo = [op printInfo]; |
Генерация данных PDF
Работа печати не должна отправлять свои результаты в принтер. Можно перенести операцию, генерируют данные PDF и пишут данным любого в NSMutableData
объект, который Вы обеспечиваете или для файла в пути, который Вы указываете. Для этого используйте PDFOperation
метод класса создать NSPrintOperation
объект вместо одного из printOperation
методы. Можно идентифицировать, генерирует ли работа печати данные PDF путем отправки его isCopyingOperation
возвращающееся сообщение, YES
в этом случае; это возвращается NO
если данные отправляются в принтер.
NSView
класс обеспечивает несколько удобных методов для генерации данных PDF. Данные могут быть возвращены в NSData
возразите или записанный в область монтажа. NSView
реализации класса dataWithPDFInsideRect:
и writePDFInsideRect:toPasteboard:
.
Эти методы создают и работают NSPrintOperation
объект, так же, как print:
метод делает, но панель печати не выведена на экран. Они все еще используют совместно используемое NSPrintInfo
возразите, предоставлены ли Вам, но не позволяйте пользователю изменять значения по умолчанию.
Печать на другом потоке
По умолчанию работа печати выполняет генерацию данных на текущем потоке. Этот поток обычно является основным потоком приложения или потоком, обрабатывающим пользовательские события. Можно сказать работе печати вместо этого порождать новый поток и генерировать задание печати на нем, с помощью setCanSpawnSeparateThread:
метод. Это позволяет Вашему приложению продолжать обрабатывать события вместо блокирования. (Операции печати, создающие данные PDF всегда, работают на текущем потоке.)