我正在尝试在我的新Cocoa应用程序中实现打印。除了缩放之外,一切都工作正常,即缩放,即75%,125%等打印
据我从Apple文档中可以看出,该程序应该根据比例因子调整从rectForPage:方法返回的矩形。我找到了一些似乎以这种方式工作的样本Apple代码,以及cocoabuilder上的旧帖子。
http://www.cocoabuilder.com/archive/cocoa/211683-scaled-printing.html
我的rectForPage:代码如下所示:
std::net::IpAddr
然而,我无法让它正常工作。无论此方法返回的是什么尺寸的矩形,输出始终以100%打印。我确实验证了actualPageRect会根据比例设置而变化,并且打印输出会裁剪到指定的矩形,但不会缩放。我有点期待Apple会根据比例因子来扩展视图,但事实并非如此。
经过长时间的调查,我放弃了这个方法,并尝试了另一种方法。现在我有rectForPage:总是返回实际的页面大小,我更改了drawRect:使用仿射变换绘制缩放输出:
NSPrintInfo *pi = [[NSPrintOperation currentOperation] printInfo];
NSSize paperSize = [pi paperSize]; // Calculate the page dimensions in points
// Convert dimensions to the scaled view
CGFloat pageScale = [[[pi dictionary] objectForKey:NSPrintScalingFactor] floatValue];
CGFloat topMargin = [pi topMargin];
CGFloat leftMargin = [pi leftMargin];
CGFloat bottomMargin = [pi bottomMargin];
CGFloat rightMargin = [pi rightMargin];
CGFloat pageHeight = (paperSize.height - topMargin - bottomMargin) / pageScale;
CGFloat pageWidth = (paperSize.width - leftMargin - rightMargin) / pageScale;
NSRect bounds = [self bounds];
NSRect actualPageRect = NSMakeRect(
NSMinX(bounds),
NSMinY(bounds),
pageWidth * pageScale,
pageHeight * pageScale);
return actualPageRect;
我还修改了knowsPageRange:方法以考虑扩展。
结果是 - 这是有效的。该程序现在生成我想要的任何缩放输出,并且它是正确分页的。但我很确定这是错误的解决方案。我认为必须有一些我遗漏的细节,它可以通过缩放从rectForPage:返回的矩形来正确缩放,但我在这一点上很难过。由于它正在工作,我可以离开它,但如果这不是正确的方法,我宁愿修复它。
答案 0 :(得分:1)
让我们从the documentation开始使用rectForPage:
的定义:
由子类实现,以确定要为页码
page
打印的视图部分。
和
一个矩形,用于定义要为
pageNumber
打印的视图区域。如果NSZeroRect
在视图的边界之外,则此方法返回pageNumber
。
所以这些是裁剪矩形。无论你绘制什么都被裁剪到这个矩形,并且该绘图被视为该页面的内容。 (你可能也会在drawRect:
中得到那个矩形,期望你跳过它之外的任何东西。)这些矩形是两个边界单位(即,相同的单位, self.bounds
是真实的单位(默认为1/72英寸)。
那么,打印信息的scalingFactor
呢?
据我所知,截至10.12.6,它不适用于AppKit - 您必须自己检索并使用scalingFactor
。 (我可能会遗漏一些东西。)
在drawRect:
中缩放绘图是完全合理的方法。您的页面矩形将保持不变;你的绘图将被缩放。如果scalingFactor
为2,则您的绘图将加倍,并且您将在页面矩形中有四分之一(每个轴上1/2)。
由于页面矩形是边界单位,因此缩放边界(使用setBoundsSize:
或scaleUnitSquareToSize:
)是另一种方式。然后你的绘图和页面rect将同时缩放。问题在于,这适用于屏幕绘图和打印图纸;当您有一个单独的视图或视图层次结构进行打印时,它最有意义。
所以,基于参考文档(以及我在10.12.6上的实验),我认为你做对了。
至于文档中的示例,我认为它是为TextEdit的页面视图编写的,其中边距是视图绘图的一部分(请注意,它会裁剪topMargin
和bottomMargin
,例如)。也就是说,只要您发现示例代码看似错误,不清楚或基于未说明的假设,我建议您file a bug。
答案 1 :(得分:0)
我为OSX / Swift 5支付2美分: (不要错过knowsPageRange,否则不会调用rectForPage。)
override func knowsPageRange(_ range: NSRangePointer) -> Bool {
return true
}
override func rectForPage(_ page: Int) -> NSRect {
guard let pi = NSPrintOperation.current?.printInfo else{return CGRect.zero}
let paperSize = pi.paperSize // Calculate the page dimensions in points
// Convert dimensions to the scaled view
let dict = pi.dictionary()
let pageScale = dict[NSPrintInfo.AttributeKey.scalingFactor] as! CGFloat
let topMargin = pi.topMargin
let leftMargin = pi.leftMargin
let bottomMargin = pi.bottomMargin
let rightMargin = pi.rightMargin
let pageHeight = (paperSize.height - topMargin - bottomMargin) / pageScale
let pageWidth = (paperSize.width - leftMargin - rightMargin) / pageScale
let bounds = self.bounds
let actualPageRect = NSRect(x: NSMinX(bounds), y: NSMinY(bounds), width: pageWidth * pageScale, height: pageHeight * pageScale)
return actualPageRect
}
在某些情况下,请确保Rect为零,否则打印将停止:否则,将无限期打印。
就我而言,我只是做了: ..
if page>1{return CGRect.zero}