Печать из приложения

NSPrintOperation возразите управляет процессом, создающим рабочее место печати. Задания печати обычно отправляются в принтер, но они могут также использоваться для генерации данных Portable Document Format (PDF) для приложения. NSPrintOperation возразите управляет полным процессом, полагаясь NSView объект генерировать фактический код. После того, как создаваемый, работа печати может быть сконфигурирована несколькими способами.

В Приложении Какао существует два класса, обеспечивающие инфраструктуру для обработки печати:

Методы Ваше использование приложения для обработки печати зависит, на котором классе она использует для его содержания.

Печать в приложении, использующем 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];

Настройка содержания для печатной страницы, не дисплея

В некоторых случаях могло бы быть предпочтительно для Вашего приложения отправить содержание в принтер, который не идентичен нарисованному на экране. Например, в то время как печатные данные должны быть отформатированы как таблица, главное окно приложения базы данных могло бы содержать интерфейс для просмотра и редактирования базы данных. В этом случае для документа нужны отдельные представления для рисования в окне и для печати к принтеру. Если у Вас есть хороший проект Контроллера представления Модели, можно легко создать пользовательское представление, которое может нарисовать специфичную для принтера версию модели данных и использовать его при создании работы печати

У Вас есть две опции для настройки содержания для печатной страницы:

  1. В drawRect Вашего приложения: метод, перейдите код как показано здесь:

    - (void)drawRect:(NSRect)r {
        if ( [NSGraphicsContext currentContextDrawingToScreen] ) {
            // Draw screen-only elements here
        } else {
            // Draw printer-only elements here
        }
        // Draw common elements here
    }
  2. Создайте представление, которое это использовало только для печати.

Когда печать к представлению возражает, что Ваше приложение использует только для печати, Вы должны:

Вы, возможно, также должны были бы скорректировать свое получение на основе атрибута в работе печати 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 всегда, работают на текущем потоке.)