0

I have an app which displays a PDFView, and I want it to print the PDF file from the view. Also, I want the Print panel to show the Page Setup Accessory (i.e. the Paper Size, Orientation and Scale settings, like in Preview, which appear as one panel of the drop-down list of options).

Currently, I'm mistakenly printing the PDFView, not the PDF document itself. This only gives me one page and includes the scrollbars in the print-out! I can't see how to init an NSPrintOperation referencing a PDFDocument rather than the PDFView.

Here's my code, which works, but isn't what I want. I presume I'll have to override either the printDocument or printOperation functions of NSDocument with similar code that defines the Panel and the Info.

func thePrintInfo() -> NSPrintInfo {
    let thePrintInfo = NSPrintInfo()
    thePrintInfo.horizontalPagination = .automatic // Tried fit
    thePrintInfo.verticalPagination = .automatic // Tried fit
    thePrintInfo.isHorizontallyCentered = true // Tried false
    thePrintInfo.isVerticallyCentered = true // Tried false
    thePrintInfo.leftMargin = 0.0
    thePrintInfo.rightMargin = 0.0
    thePrintInfo.topMargin = 0.0
    thePrintInfo.bottomMargin = 0.0
    thePrintInfo.jobDisposition = .spool
    return thePrintInfo
}

// Need to show the 'Page Setup' Options as an Accessory
// e.g. Paper size, orientation.
@IBAction func printContent(_ sender: Any) {
    let printOperation = NSPrintOperation(view: thePDFView, printInfo: thePrintInfo())
    let printPanel = NSPrintPanel()
    printPanel.options = [
        NSPrintPanel.Options.showsCopies,
        NSPrintPanel.Options.showsPrintSelection,
        NSPrintPanel.Options.showsPageSetupAccessory,
        NSPrintPanel.Options.showsPreview
    ]
    printOperation.printPanel = printPanel
    printOperation.run()
}
benwiggy
  • 1,440
  • 17
  • 35
  • What should be printed, the view or the pdf-document? See [printOperation(for:scalingMode:autoRotate:)](https://developer.apple.com/documentation/pdfkit/pdfdocument/1436075-printoperation) – Willeke Aug 17 '19 at 16:33
  • @Willeke That's the problem! I'm currently printing the view, but I want to print the document. There doesn't seem to be a way of initializing an NSPrintOperation without referencing a view. – benwiggy Aug 18 '19 at 07:36
  • 1
    How about the linked `printOperation(for:scalingMode:autoRotate:)` of `PDFDocument`? – Willeke Aug 18 '19 at 08:07
  • Can you give me a clue how I use it in the context of the app, and how I get the PrintPanel settings in there? – benwiggy Aug 18 '19 at 09:01
  • 1
    I think it's something like `let printOperation = thePDFDocument.printOperation(for:thePrintInfo(), scalingMode:.pageScaleDownToFit, autoRotate:true)` instead of `let printOperation = NSPrintOperation(view: thePDFView, printInfo: thePrintInfo())`. – Willeke Aug 18 '19 at 09:38

1 Answers1

1

Based on @Willeke's comments, I've come up with the following, which seems to work well. (Minor quibble is that the Print dialog isn't a sheet.) If anyone has any improvements, please post a better answer.

@IBAction func printContent(_ sender: Any) {
   let printOperation = thePDFView.document?.printOperation(for: thePrintInfo(), scalingMode: .pageScaleNone, autoRotate: true)
printOperation?.printPanel = thePrintPanel()
printOperation?.run()
}
benwiggy
  • 1,440
  • 17
  • 35
  • 1
    [runModal(for:delegate:didRun:contextInfo:)](https://developer.apple.com/documentation/appkit/nsprintoperation/1532065-runmodal) displays a sheet. – Willeke Aug 18 '19 at 15:28
  • @Willeke Yes, I saw that, but got scared by delegates and selectors and pointers. I'll have a go. – benwiggy Aug 18 '19 at 15:36
  • 1
    The delegate, selector and context are optional: `printOperation.runModal(for: window, delegate: nil, didRun: nil, contextInfo: nil)` – Willeke Aug 19 '19 at 08:30
  • @Willeke Hmm. Not quite sure what my Window is. I don't think I've defined one. Anyway, it's working fine just with run(). – benwiggy Aug 19 '19 at 18:57
  • `window` is the parent window of the sheet. – Willeke Aug 19 '19 at 19:53
  • That's another question, I think. Thanks for your help. – benwiggy Aug 20 '19 at 07:27