我正在尝试打印文档。该文档是一个 NSImageRep 数组,或者是一个 NSPDFImageRep,它有多个页面。我无法弄清楚如何使用 NSPrintOperation 类来打印它。
NSPrintOperation 似乎需要一个 NSView 来打印。我是否需要手动将每个图像添加到视图中的计算位置,然后让它进行分页?这似乎不符合 Cocoa 的精神......我是否缺少一些技术?
我正在尝试打印文档。该文档是一个 NSImageRep 数组,或者是一个 NSPDFImageRep,它有多个页面。我无法弄清楚如何使用 NSPrintOperation 类来打印它。
NSPrintOperation 似乎需要一个 NSView 来打印。我是否需要手动将每个图像添加到视图中的计算位置,然后让它进行分页?这似乎不符合 Cocoa 的精神......我是否缺少一些技术?
尽管这有一个公认的答案,但它并没有真正回答基本问题,只是提供了一种解决方法。
我刚刚遇到了类似的问题(我有一组对象,每个对象都由同一NSView
个子类呈现,每页一个)。这就是我解决它的方法,没有巴洛克式的废话,即创建一个包含所有页面的巨型视图......
1)我们有一个NSView
子类,它有一个与之关联的模型(NSImage
在你的情况下,ModelData
在我的情况下)
class BaseView: NSView {
var modelData: ModelData /* Whatever your view needs to draw */
//...
}
var models: [ModelData]
2)我们在您的文档控制器中有一个数组。
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)
}
您可以创建显示您要打印的内容的视图。然后你用它来创建打印操作。
您通常会创建一个显示图像的视图。您实现了一种算法来确定要在哪个页面上显示什么图像。然后返回可打印的页数并实现打印特定页面的方法。
请参阅Print Programming Topics,或者我在本书下面引用的完整示例有分页,我没有在这里包含。查看自定义分页以获取更多提示。
如果您有基于文档的应用程序和要转储到打印机的视图,那么在我们的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;
}
您可以在 Hillegass 的 Cocoa Programming For Mac OS X 中的第 27 章“打印”中查找更多详细信息。
您无法打印无法绘制的东西。NSView 是您绘制想要打印的内容的方式。您可以使用 NSView 的分页方法创建一个仅用于打印的 NSView 子类,该子类决定您希望打印的工作方式(例如,您是否想要一个 NSImageRep 用于页面 - 任何大小的页面?)。只需覆盖knowsPageRange:
以返回 YES。
对于未来的参考,我相信答案是 PDFViews。您可以一次将 PDFPage 添加到 PDFView(通过 PDFDocument),然后您可以使用 printWithInfo:autoRotate 进行打印:
至少在理论上,我已经创建了视图,并且出现了打印对话框,但是当我点击“打印”时,对话框并没有消失......
但这是一个不同的问题。