Не удается заставить iOS Print Renderer правильно рисовать
ХОРОШО. Похоже, на это не хватает примеров, и я довольно озадачен.
Я пытаюсь сделать пользовательский рендерер страницы печати; тип, который полностью настраивает вывод, а не тот, который использует существующее представление.
Действительно странная вещь - то, что я смог сделать это в ObjC пару лет назад, и я не могу сделать то же самое в Swift.
Я должен упомянуть, что я использую предварительную версию (бета-версию 5) Xcode и Swift 4 (что практически не отличается от Swift 3 в моем проекте).
Это полностью открытый проект, так что ничего не скрыто; тем не менее, он все еще находится в стадии разработки и является движущейся целью.
Кстати: игнорировать делегатский класс. Я просто мотался, пытаясь разобраться. Я пока не планирую делать какие-либо делегаты. В частности, мой вопрос касается того, что здесь происходит:
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)
}
Который все называется здесь:
@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, например:
Это должен быть список названий собраний, бегущих по странице.
Чтобы попасть сюда, нужно запустить приложение, подождать, пока оно не подключится к серверу, а затем нажать большую кнопку. Вы получите список и нажмите кнопку "Действие" в верхней части экрана.
Я не удосужился выйти за рамки предварительного просмотра, поскольку это даже не работает. Этот список - единственный, который я написал прямо сейчас, и я только на стадии простой печати названий собраний, чтобы убедиться, что у меня есть правильный основной макет.
Что я, очевидно, не знаю.
Есть идеи?
1 ответ
Отлично. Я понял, в чем проблема.
Я пытался сделать это, используя подпрограммы 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
}