打印NSDocument

时间:2010-03-18 19:47:05

标签: objective-c cocoa nsview nsdocument nsprintoperation

我正在尝试打印文档。该文档是一个NSImageReps数组,或一个NSPDFImageRep数组,它有多个页面。我无法弄清楚如何使用NSPrintOperation类来打印它。

NSPrintOperation似乎需要NSView才能打印。我是否需要在计算位置手动将每个图像添加到视图中,然后让它进行分页?这似乎不符合Cocoa的精神......是否有一些我缺少的技术?

4 个答案:

答案 0 :(得分:2)

尽管有一个已接受的答案,但它并没有真正回答基本问题,只是给出一个解决方法。

我遇到了类似的问题(我有一个对象数组,每个对象都由同一个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 :(得分:1)

您无法打印无法绘制的内容。 NSView是您绘制要打印的内容的方式。您可以使用NSView的分页方法创建一个仅用于打印的NSView子类来决定打印的工作方式(例如,您是否需要一个NSImageRep页面 - 任何大小的页面?)。只需覆盖knowsPageRange:即可返回YES。

答案 2 :(得分:1)

您可以创建显示要打印内容的视图。然后使用它来创建打印操作。

您通常会创建一个显示图像的视图。您可以实现一种算法来确定要在哪个页面上显示的图像。然后返回可打印的页数,并实现打印特定页面的方法。

  • 如果您有10张图片而且您想要 每页打印一个很容易。
  • 如果要每页打印记录 你有100条记录 计算你可以记录多少条记录 适合页面(使用当前字体 每条记录的大小和行数。)
  • 然后你从每个记录中找出答案 页面你需要多少页 显示所有记录 - 这是你的 页数(页数范围)。
  • 当要求打印具体时 您选择记录的页面范围 应该在给定页面上显示 显示它们。
  • 请参阅以下有关如何参考的内容 实施这些步骤。请参阅the custom pagination信息 示例如何实现这些步骤,并不困难。

请参阅Print Programming Topics,或者我在书中引用的完整示例包含了我未包含在内的分页。请查看the custom pagination以获取更多提示。

如果您有基于文档的应用程序和要转储到打印机的视图,那么在MyDocument(或任何您称之为)的扩展NSDocument中,您将实现:

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

然后视图使用标准drawRect:进行绘制。

示例,此处PeopleView仅提取table人详细信息,此处需要NSDictonaryemployees

- (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可可编程”。

答案 3 :(得分:0)

为了将来参考,我相信答案是PDFViews。您可以一次性将PDFPage添加到PDFView(通过PDF文档),然后您可以使用printWithInfo打印:autoRotate:

理论上至少,我已经创建了视图,并且出现了打印对话框,但是当我点击“打印”时,对话框不会消失......

但这是一个不同的问题。