Печать NSDocument - PullRequest
       23

Печать NSDocument

4 голосов
/ 18 марта 2010

Я пытаюсь распечатать документ. Документ представляет собой массив NSImageReps или один NSPDFImageRep, который имеет несколько страниц. У меня возникают проблемы с выяснением, как использовать класс NSPrintOperation для печати этого.

NSPrintOperation, кажется, нуждается в NSView для печати. Нужно ли вручную добавлять каждое изображение в представление в рассчитанной позиции, а затем разрешить разбиение на страницы? кажется, что это не в духе какао ... есть какая-то техника, которую я пропускаю?

Ответы [ 4 ]

2 голосов
/ 13 апреля 2017

Несмотря на то, что он имеет принятый ответ, он на самом деле не отвечает на основной вопрос, а лишь дает обходной путь.

У меня просто была похожая проблема (у меня есть массив объектов, каждый из которых представлен одним и тем же подклассом NSView, по одному на страницу). Вот как я решил это, без всякой барочной чепухи создания одного гигантского представления, которое содержит все страницы ...

1) У нас есть NSView подкласс, с которым связана модель (NSImage в вашем случае, ModelData в моем случае)

class BaseView: NSView {
    var modelData: ModelData /* Whatever your view needs to draw */
    //...
}

2) У нас есть массив var models: [ModelData] в вашем контроллере документов.

3) Создайте новый подкласс, который будет отображать принтер.

class PrinterView: BaseView {
    var pageIndex: Int = 1
    var modelArray: [ModelData]

    init(frame: NSRect, models: [ModelData]) {
        self.modelArray = models
        super.init(frame: frame)
    }

    required init?(coder: NSCoder) {
        fatalError("invalid initializer")
    }

    override func knowsPageRange(_ range: NSRangePointer) -> Bool {
        range.pointee.location = 1
        range.pointee.length = self.modelArray.count
        return true
    }

    override func rectForPage(_ page: Int) -> NSRect {
        self.pageIndex = page
        return self.bounds
    }

    override func draw(_ dirtyRect: NSRect) {
        self.model = self.modelArray[self.page - 1] // Pages are 1, not 0, based
        super.draw(dirtyRect)
    }
} // That's it! That's all...

4) Сделайте это в вашем контроллере документов:

override func printOperation(withSettings printSettings: [String : Any]) throws -> NSPrintOperation {
    self.printInfo.horizontalPagination = .fitPagination
    self.printInfo.verticalPagination = .clipPagination
    let printView = PrinterView(size: self.printInfo.paperSize, models: self.models)

    return NSPrintOperation(view: printView, printInfo: self.printInfo)
}
1 голос
/ 19 марта 2010

Вы можете создать вид, который отображает то, что вы хотите напечатать. Затем вы используете его для создания операции печати. ​​

Обычно вы создаете представление, отображающее ваше изображение. Вы реализуете алгоритм, чтобы выяснить, какое изображение вы хотите отобразить на какой странице. Затем вы возвращаете количество страниц, доступных для печати, и применяете метод для печати конкретной страницы.

  • Если у вас есть 10 изображений, и вы хотите напечатать по одной на странице, это просто.
  • Если вы хотите распечатать записи на странице и у вас есть 100 записей, то вы посчитайте, сколько записей вы можете поместиться на странице (используя текущий шрифт размер и количество строк в записи).
  • Тогда вы выясните из записей в страница, сколько страниц вам нужно показать все записи - это ваше количество страниц (диапазон страниц).
  • При запросе на печать диапазон страниц, которые вы выбираете записи это должно быть показано на данной странице и показать их.
  • См. Ссылки ниже о том, как реализовать эти шаги. См. пользовательская нумерация страниц информация для Пример того, как реализовать эти шаги, это не сложно.

См. Темы программирования печати , или полный пример, на который я ссылаюсь ниже из книги, имеет нумерацию страниц, которую я здесь не включил. Посмотрите на пользовательскую нумерацию страниц , чтобы узнать больше подсказок.

Если у вас есть приложение на основе документов и представление, которое вы хотите выгрузить на принтер, то в нашем MyDocument (или как вы его называете), который расширяет NSDocument, вы бы реализовали:

- (NSPrintOperation *)printOperationWithSettings:(NSDictionary *)ps
                                           error:(NSError **)e

Вид затем использует стандартный drawRect: для рисования.

Например, здесь PeopleView просто рисует table данных о людях, здесь требуется NSDictonary людей employees здесь:

- (NSPrintOperation *)printOperationWithSettings:(NSDictionary *)ps
                                           error:(NSError **)e
{
    PeopleView * view = [[PeopleView alloc] initWithPeople:employees];
    NSPrintInfo * printInfo = [self printInfo];
    NSPrintOperation * printOp
        = [NSPrintOperation printOperationWithView:view
                                         printInfo:printInfo];
    [view release];
    return printOp;
}

Более подробную информацию вы можете найти в главе 27, «Печать», в Программе какао Hillegass для Mac OS X.

1 голос
/ 18 марта 2010

Вы не можете напечатать что-то, что не может быть нарисовано. NSView - это то, как вы рисуете то, что хотите напечатать. Вы можете создать подкласс NSView только для печати, который решает, как вы хотите, чтобы печать работала (например, хотите ли вы один NSImageRep для страницы - ЛЮБОГО размера страницы?), Используя методы разбиения на страницы NSView. Просто переопределите knowsPageRange:, чтобы вернуть YES.

0 голосов
/ 19 марта 2010

Для справки в будущем, я считаю, что ответ PDFViews. вы можете сразу добавить PDFPage в PDFView (с помощью PDFDocument), а затем распечатать с помощью printWithInfo: autoRotate:

В теории, по крайней мере, я создал вид, и появляется диалоговое окно печати, но когда я нажимаю "печать", диалоговое окно не исчезает ...

Но это другой вопрос.

...