Привет, сообщество потока StackOver,
Я работал над задачей, в которой мне нужно преобразовать содержимое таблицы (которая содержит представления заголовков разделов и представления строк в нем) в данные формы pdf, а затем использовать эти данные для печати. Преобразовать содержимое tableView в одну страницу pdf очень просто. Но в приведенном ниже коде я визуализирую видимый контент на одной странице, а затем прокручиваю до следующих строк. Это работает для меня, но заголовок раздела печатается на каждой странице, которая скрывает первую строку каждой страницы. Я пробовал рендерить заголовок раздела отдельно, а затем отдельные ячейки; безуспешно.
Прилагаю сюда код печати.
pdfDataWithTableView - функция используется для генерации данных для печати
`
class ReportGenerateV C : UIViewController {
//Views on the top half of the screen
@IBOutlet weak private var printBtn: UIButton!
@IBOutlet weak private var tblVw: UITableView!
@IBOutlet weak private var emailBtn: UIButton!
@IBOutlet weak private var backBtn: UIButton!
@IBOutlet weak var lblCategory: UILabel!
//Public
var displayCategories: [Category]!
//
// MARK:- View life Cycle
override func viewDidLoad() {
super.viewDidLoad()
//Layout settings - Header view for the cells
let headerNib = UINib.init(nibName: "ReportHeaderView", bundle: Bundle.main)
tblVw.register(headerNib, forHeaderFooterViewReuseIdentifier: "ReportHeaderView")
}
// MARK: - IB ACTIONS
@IBAction private func backButtonAction(_ sender: Any) {
self.navigationController?.popViewController(animated: true)
}
@IBAction func printReportingBtnAction(_ sender: Any) {
self.tblVw.setContentOffset(CGPoint(x: 0, y: UIApplication.shared.statusBarFrame.height ), animated: true)
self.printReportPDFViewControllerWithName(self.getUrlOfTableData(self.tblVw))
self.tblVw.setContentOffset(CGPoint(x: 0, y: UIApplication.shared.statusBarFrame.height ), animated: true)
}
@IBAction func emailReportingBtnAction(_ sender: Any) {
let mailComposeVC = MFMailComposeViewController()
if MFMailComposeViewController.canSendMail() {
mailComposeVC.mailComposeDelegate = self
mailComposeVC.setToRecipients(["quantumliferyan@gmail.com","admin@quantumhealthapps.com","jochar48@icloud.com", "mediteckhealingprime@gmail.com"])
mailComposeVC.setSubject("")
mailComposeVC.setMessageBody("", isHTML: false)
mailComposeVC.addAttachmentData(self.pdfDataWithTableView(self.tblVw) as Data, mimeType: "application/pdf", fileName: "result")
self.present(mailComposeVC, animated: true, completion: nil)
} else {
Utilities().showAlert(message: AlertMessagesConsts.kEmailAccountAddAlert.rawValue)
}
}
private func printReportPDFViewControllerWithName( _ pdfFileNameStr: URL)
{
if UIPrintInteractionController.canPrint(pdfFileNameStr) {
let printInfo = UIPrintInfo(dictionary: nil)
printInfo.jobName = pdfFileNameStr.lastPathComponent
printInfo.outputType = .photo
let printController = UIPrintInteractionController.shared
printController.printInfo = printInfo
printController.showsNumberOfCopies = false
printController.printingItem = pdfFileNameStr
printController.present(animated: true, completionHandler: nil)
}
}
private func pdfDataWithTableView(_ tableView: UITableView) -> NSMutableData
{
//
var priorBounds = tableView.bounds
let fittedSize = tableView.sizeThatFits(CGSize(width:priorBounds.size.width, height:tableView.contentSize.height))
let pdfPageBounds = CGRect(x:0, y:0, width:tableView.frame.width, height:tableView.frame.height)
let pdfData = NSMutableData()
UIGraphicsBeginPDFContextToData(pdfData, pdfPageBounds,nil)
var section = 0
while priorBounds.origin.y < fittedSize.height
{
print(tableView.visibleHeaderViews)
UIGraphicsBeginPDFPageWithInfo(pdfPageBounds, nil)
UIGraphicsGetCurrentContext()!.saveGState()
UIGraphicsGetCurrentContext()!.translateBy(x: 0, y: -priorBounds.origin.y)
tableView.layer.render(in: UIGraphicsGetCurrentContext()!)
UIGraphicsGetCurrentContext()!.translateBy(x: priorBounds.width, y: -priorBounds.origin.y);
UIGraphicsGetCurrentContext()!.restoreGState()
priorBounds.origin.y += pdfPageBounds.size.height
section = section + 1
var sectionPriorBounds = priorBounds
sectionPriorBounds.origin.y -= 63
tableView.scrollRectToVisible(sectionPriorBounds, animated: false)
}
UIGraphicsEndPDFContext()
return pdfData
}
private func getUrlOfTableData(_ paramTbl: UITableView) -> URL {
let pdfData = self.pdfDataWithTableView(paramTbl)
//let pdfData = PdfGenerator.PDFWithScrollView(scrollview: paramTbl)
var docURL = (FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)).last! as URL
docURL = docURL.appendingPathComponent("myDocument.pdf")
pdfData.write(to: docURL as URL, atomically: true)
return docURL
}
static func fromStoryboardObj(_ storyboard: UIStoryboard = UIStoryboard(name: StoryBoardNameKey.kDoctorSB.rawValue, bundle: nil)) -> ReportGenerateVC
{
let controller = storyboard.instantiateViewController(withIdentifier: NamesVCs.kReportGenerateVC.rawValue) as! ReportGenerateVC
return controller
}
}
расширение ReportGenerateV C: UITableViewDelegate, UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
displayCategories.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 63
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 63
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return displayCategories[section].subCatArr.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let systemCell = tableView.dequeueReusableCell(withIdentifier: CellIdentifiersKey.kReportChildCell.rawValue, for: indexPath) as! ReportChildCell
let subCatData : [SubCategory]! = displayCategories[indexPath.section].subCatArr
systemCell.setCellInfo(subCatData[indexPath.row])
return systemCell
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: CellIdentifiersKey.kReportHeaderView.rawValue) as! ReportHeaderView
headerView.setHeaderInfo(displayCategories[section])
return headerView
}
}
расширение ReportGenerateV C : MFMailComposeViewControllerDelegate {// MARK: - MFMail compose method fun c mailComposeController (_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeViewController, error: Error?) {Controller.dismiss (animated: true, completion: nil)}}
расширение UITableView {
/// The section header views that are visible in the table view.
var visibleHeaderViews: [UITableViewHeaderFooterView] {
var headerViews = [UITableViewHeaderFooterView]()
guard let indexPaths = indexPathsForVisibleRows else { return headerViews }
for indexPath in indexPaths {
if let headerView = headerView(forSection: indexPath.section) {
headerViews.append(headerView)
}
}
return headerViews
}
} `