我试图在SwiftUI上打印macOS视图的内容。根据文档,这似乎是通过给NSPrintOperation一个由NSHostingView创建的NSView来实现的。SwiftUI视图的主体包含几个文本视图和一个图像视图,这些视图周围有边框。所有文本都会被打印出来,但是图像和边框是不可见的。要让这件事成功,还需要别的什么吗?
这里有一个示例来演示这个问题。只需创建一个新的macOS应用程序,用下面的代码替换ContentView,然后启用签名和功能中的打印:
struct ContentView: View {
var body: some View {
VStack {
Button("Print", action: self.onPrint )
Divider()
Print_Preview()
}
}
private func onPrint() {
let pi = NSPrintInfo.shared
pi.topMargin = 0.0
pi.bottomMargin = 0.0
pi.leftMargin = 0.0
pi.rightMargin = 0.0
pi.orientation = .landscape
pi.isHorizontallyCentered = false
pi.isVerticallyCentered = false
pi.scalingFactor = 1.0
let rootView = Print_Preview()
let view = NSHostingView(rootView: rootView)
view.frame.size = CGSize(width: 300, height: 300)
let po = NSPrintOperation(view: view, printInfo: pi)
po.printInfo.orientation = .landscape
po.showsPrintPanel = true
po.showsProgressPanel = true
po.printPanel.options.insert(NSPrintPanel.Options.showsPaperSize)
po.printPanel.options.insert(NSPrintPanel.Options.showsOrientation)
if po.run() {
print("In Print completion")
}
}
struct Print_Preview: View {
var body: some View {
VStack(alignment: .leading) {
Text("Bordered Text Above Bordered Image")
.font(.system(size: 8))
.padding(5)
.border(Color.black, width: 2)
Image(systemName: "printer")
.resizable()
.padding(5)
.border(Color.black, width: 2)
.frame(width: 100, height: 100)
Text("Bordered Text Below Bordered Image")
.font(.system(size: 8))
.padding(5)
.border(Color.black, width: 2)
}
.padding()
.foregroundColor(Color.black)
.background(Color.white)
.frame(width: 200, height: 200)
}
}
}这里还有应用程序和打印面板的截图。


发布于 2022-04-10 00:25:13
感谢@Willeke给出了带有指针的评论,并感谢@ that 2120275提出了一个不同的问题,而这个问题恰好包含了解决问题所需的技巧。解决方案是从NSImageView返回的NSView中创建NSHostingView,然后打印该NSImageView而不是原始的NSView。
通过替换这两行代码,可以使上面的示例代码正常工作:
view.frame.size = CGSize(width: 300, height: 300)
let po = NSPrintOperation(view: view, printInfo: pi)有以下几点:
let contentRect = NSRect(x: 0, y: 0, width: 300, height: 300)
view.frame.size = contentRect.size
let newWindow = NSWindow(
contentRect: contentRect,
styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
backing: .buffered, defer: false)
newWindow.contentView = view
let myNSBitMapRep = newWindow.contentView!.bitmapImageRepForCachingDisplay(in: contentRect)!
newWindow.contentView!.cacheDisplay(in: contentRect, to: myNSBitMapRep)
let myNSImage = NSImage(size: myNSBitMapRep.size)
myNSImage.addRepresentation(myNSBitMapRep)
let nsImageView = NSImageView(frame: contentRect)
nsImageView.image = myNSImage
let po = NSPrintOperation(view: nsImageView, printInfo: pi)https://stackoverflow.com/questions/71773747
复制相似问题