Despite this having an accepted answer, it doesn't really answer the basic question, just gives a work-around.
I just had a similar problem (I have an array of objects each rendered by the same NSView
subclass, one per page). Here's how I solved it, without the baroque nonsense of creating one giant view that holds all the pages...
1) We have an NSView
subclass that has a model associated with it (NSImage
in your case, ModelData
in my case)
class BaseView: NSView {
var modelData: ModelData /* Whatever your view needs to draw */
//...
}
2) We have an array var models: [ModelData]
in your document controller.
3) Create a new subclass that will be the printer view.
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) Do this in your document controller:
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)
}