无法让 iOS 打印渲染器正确绘制
Can't Get iOS Print Renderer to Draw Properly
好的。这方面的例子似乎很少,我很困惑。
我正在尝试制作自定义打印页面渲染器;完全自定义输出的类型,而不是使用现有视图的类型。
真正奇怪的是,几年前我能够在 ObjC 中做到这一点,但我似乎无法在 Swift 中做同样的事情。
我应该提一下,我使用的是 Xcode 的预发布版 (Beta 5),以及 Swift 4(与 Swift 3 几乎没有区别,在我的项目)。
这是一个完全open-source的项目,所以没有任何隐藏;但是,它仍处于开发阶段,并且是一个移动的目标。
This is the page renderer class.
顺便说一句: 忽略委托 class。我只是四处乱窜,想把事情弄清楚。我 [还] 不打算做任何代表的事情。
特别是,我的问题涉及正在发生的事情 here:
override func drawContentForPage(at pageIndex: Int, in contentRect: CGRect) {
let perMeetingHeight: CGFloat = self.printableRect.size.height / CGFloat(self.actualNumberOfMeetingsPerPage)
let startingPoint = max(self.maxMeetingsPerPage * pageIndex, 0)
let endingPointPlusOne = min(self.maxMeetingsPerPage, self.actualNumberOfMeetingsPerPage)
for index in startingPoint..<endingPointPlusOne {
let top = self.printableRect.origin.y + (CGFloat(index) * perMeetingHeight)
let meetingRect = CGRect(x: self.printableRect.origin.x, y: top, width: self.printableRect.size.width, height: perMeetingHeight)
self.drawMeeting(at: index, in: meetingRect)
}
}
func drawMeeting(at meetingIndex: Int, in contentRect: CGRect) {
let myMeetingObject = self.meetings[meetingIndex]
var top: CGFloat = contentRect.origin.y
let topLabelRect = CGRect(x: contentRect.origin.x, y: 0, width: contentRect.size.width, height: self.meetingNameHeight)
top += self.meetingNameHeight
let meetingNameLabel = UILabel(frame: topLabelRect)
meetingNameLabel.backgroundColor = UIColor.clear
meetingNameLabel.font = UIFont.boldSystemFont(ofSize: 30)
meetingNameLabel.textAlignment = .center
meetingNameLabel.textColor = UIColor.black
meetingNameLabel.text = myMeetingObject.name
meetingNameLabel.draw(topLabelRect)
}
全部调用自here:
@IBAction override func actionButtonHit(_ sender: Any) {
let sharedPrintController = UIPrintInteractionController.shared
let printInfo = UIPrintInfo(dictionary:nil)
printInfo.outputType = UIPrintInfoOutputType.general
printInfo.jobName = "print Job"
sharedPrintController.printPageRenderer = BMLT_MeetingSearch_PageRenderer(meetings: self.searchResults)
sharedPrintController.present(from: self.view.frame, in: self.view, animated: false, completionHandler: nil)
}
这是怎么回事,页面上的所有内容都堆积在顶部。我试图在一页上打印一个连续的会议列表,但它们都被绘制在 y=0 位置,如下所示:
这应该是会议名称列表,运行 在页面下方。
到达这里的方法是启动应用程序,等待它连接到服务器,然后点击大按钮。您将获得一个列表,然后按屏幕顶部的 "Action" 按钮。
我没有费心去超越预览,因为它甚至不起作用。该列表是我目前唯一连接的列表,我正处于简单打印会议名称以确保基本布局正确的阶段。
我显然不知道。
有什么想法吗?
好的。我知道问题出在哪里了。
我正在尝试使用 UIKit 例程来执行此操作,该例程假定相当高级的绘图上下文。 drawText(in: CGRect) 是我的灯泡。
我需要使用较低级别的、基于上下文的绘图来完成所有工作,而不要使用 UIKit。
下面是我现在如何实现 drawMeeting 例程(我已经更改了我绘制的内容以显示更多相关信息)。我还在努力,它会变大:
func drawMeeting(at meetingIndex: Int, in contentRect: CGRect) {
let myMeetingObject = self.meetings[meetingIndex]
var remainingRect = contentRect
if (1 < self.meetings.count) && (0 == meetingIndex % 2) {
if let drawingContext = UIGraphicsGetCurrentContext() {
drawingContext.setFillColor(UIColor.black.withAlphaComponent(0.075).cgColor)
drawingContext.fill(contentRect)
}
}
var attributes: [NSAttributedStringKey : Any] = [:]
attributes[NSAttributedStringKey.font] = UIFont.italicSystemFont(ofSize: 12)
attributes[NSAttributedStringKey.backgroundColor] = UIColor.clear
attributes[NSAttributedStringKey.foregroundColor] = UIColor.black
let descriptionString = NSAttributedString(string: myMeetingObject.description, attributes: attributes)
let descriptionSize = contentRect.size
var stringRect = descriptionString.boundingRect(with: descriptionSize, options: [NSStringDrawingOptions.usesLineFragmentOrigin,NSStringDrawingOptions.usesFontLeading], context: nil)
stringRect.origin = contentRect.origin
descriptionString.draw(at: stringRect.origin)
remainingRect.origin.y -= stringRect.size.height
}
好的。这方面的例子似乎很少,我很困惑。
我正在尝试制作自定义打印页面渲染器;完全自定义输出的类型,而不是使用现有视图的类型。
真正奇怪的是,几年前我能够在 ObjC 中做到这一点,但我似乎无法在 Swift 中做同样的事情。
我应该提一下,我使用的是 Xcode 的预发布版 (Beta 5),以及 Swift 4(与 Swift 3 几乎没有区别,在我的项目)。
这是一个完全open-source的项目,所以没有任何隐藏;但是,它仍处于开发阶段,并且是一个移动的目标。
This is the page renderer class.
顺便说一句: 忽略委托 class。我只是四处乱窜,想把事情弄清楚。我 [还] 不打算做任何代表的事情。 特别是,我的问题涉及正在发生的事情 here:
override func drawContentForPage(at pageIndex: Int, in contentRect: CGRect) {
let perMeetingHeight: CGFloat = self.printableRect.size.height / CGFloat(self.actualNumberOfMeetingsPerPage)
let startingPoint = max(self.maxMeetingsPerPage * pageIndex, 0)
let endingPointPlusOne = min(self.maxMeetingsPerPage, self.actualNumberOfMeetingsPerPage)
for index in startingPoint..<endingPointPlusOne {
let top = self.printableRect.origin.y + (CGFloat(index) * perMeetingHeight)
let meetingRect = CGRect(x: self.printableRect.origin.x, y: top, width: self.printableRect.size.width, height: perMeetingHeight)
self.drawMeeting(at: index, in: meetingRect)
}
}
func drawMeeting(at meetingIndex: Int, in contentRect: CGRect) {
let myMeetingObject = self.meetings[meetingIndex]
var top: CGFloat = contentRect.origin.y
let topLabelRect = CGRect(x: contentRect.origin.x, y: 0, width: contentRect.size.width, height: self.meetingNameHeight)
top += self.meetingNameHeight
let meetingNameLabel = UILabel(frame: topLabelRect)
meetingNameLabel.backgroundColor = UIColor.clear
meetingNameLabel.font = UIFont.boldSystemFont(ofSize: 30)
meetingNameLabel.textAlignment = .center
meetingNameLabel.textColor = UIColor.black
meetingNameLabel.text = myMeetingObject.name
meetingNameLabel.draw(topLabelRect)
}
全部调用自here:
@IBAction override func actionButtonHit(_ sender: Any) {
let sharedPrintController = UIPrintInteractionController.shared
let printInfo = UIPrintInfo(dictionary:nil)
printInfo.outputType = UIPrintInfoOutputType.general
printInfo.jobName = "print Job"
sharedPrintController.printPageRenderer = BMLT_MeetingSearch_PageRenderer(meetings: self.searchResults)
sharedPrintController.present(from: self.view.frame, in: self.view, animated: false, completionHandler: nil)
}
这是怎么回事,页面上的所有内容都堆积在顶部。我试图在一页上打印一个连续的会议列表,但它们都被绘制在 y=0 位置,如下所示:
这应该是会议名称列表,运行 在页面下方。
到达这里的方法是启动应用程序,等待它连接到服务器,然后点击大按钮。您将获得一个列表,然后按屏幕顶部的 "Action" 按钮。
我没有费心去超越预览,因为它甚至不起作用。该列表是我目前唯一连接的列表,我正处于简单打印会议名称以确保基本布局正确的阶段。
我显然不知道。
有什么想法吗?
好的。我知道问题出在哪里了。
我正在尝试使用 UIKit 例程来执行此操作,该例程假定相当高级的绘图上下文。 drawText(in: CGRect) 是我的灯泡。
我需要使用较低级别的、基于上下文的绘图来完成所有工作,而不要使用 UIKit。
下面是我现在如何实现 drawMeeting 例程(我已经更改了我绘制的内容以显示更多相关信息)。我还在努力,它会变大:
func drawMeeting(at meetingIndex: Int, in contentRect: CGRect) {
let myMeetingObject = self.meetings[meetingIndex]
var remainingRect = contentRect
if (1 < self.meetings.count) && (0 == meetingIndex % 2) {
if let drawingContext = UIGraphicsGetCurrentContext() {
drawingContext.setFillColor(UIColor.black.withAlphaComponent(0.075).cgColor)
drawingContext.fill(contentRect)
}
}
var attributes: [NSAttributedStringKey : Any] = [:]
attributes[NSAttributedStringKey.font] = UIFont.italicSystemFont(ofSize: 12)
attributes[NSAttributedStringKey.backgroundColor] = UIColor.clear
attributes[NSAttributedStringKey.foregroundColor] = UIColor.black
let descriptionString = NSAttributedString(string: myMeetingObject.description, attributes: attributes)
let descriptionSize = contentRect.size
var stringRect = descriptionString.boundingRect(with: descriptionSize, options: [NSStringDrawingOptions.usesLineFragmentOrigin,NSStringDrawingOptions.usesFontLeading], context: nil)
stringRect.origin = contentRect.origin
descriptionString.draw(at: stringRect.origin)
remainingRect.origin.y -= stringRect.size.height
}