Printing the view in iOS with Swift
I have found the answer to my question by modifying the code found here: AirPrint contents of a UIView
//create an extension to covert the view to an image
extension UIView {
func toImage() -> UIImage {
UIGraphicsBeginImageContextWithOptions(bounds.size, false, UIScreen.mainScreen().scale)
drawViewHierarchyInRect(self.bounds, afterScreenUpdates: true)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
}
//In your view controller
@IBAction func printButton(sender: AnyObject) {
let printInfo = UIPrintInfo(dictionary:nil)
printInfo.outputType = UIPrintInfoOutputType.General
printInfo.jobName = "My Print Job"
// Set up print controller
let printController = UIPrintInteractionController.sharedPrintController()
printController.printInfo = printInfo
// Assign a UIImage version of my UIView as a printing iten
printController.printingItem = self.view.toImage()
// If you want to specify a printer
guard let printerURL = URL(string: "Your printer URL here, e.g. ipps://HPDC4A3E0DE24A.local.:443/ipp/print") else { return }
guard let currentPrinter = UIPrinter(url: printerURL) else { return }
printController.print(to: currentPrinter, completionHandler: nil)
// Do it
printController.presentFromRect(self.view.frame, inView: self.view, animated: true, completionHandler: nil)
}
Is it possible to print the UI Content Presented on Screen | Swift
Step 1: First for converting your UIView into image , add this extension:
extension UIView {
func toImage() -> UIImage {
UIGraphicsBeginImageContextWithOptions(bounds.size, false, UIScreen.mainScreen().scale)
drawViewHierarchyInRect(self.bounds, afterScreenUpdates: true)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
}
Step 2: Add this into your button action for print:
@IBAction func printButton(sender: AnyObject) {
let printInfo = UIPrintInfo(dictionary:nil)
printInfo.outputType = UIPrintInfoOutputType.General
printInfo.jobName = "My UIView"
let printController = UIPrintInteractionController.sharedPrintController()
printController.printInfo = printInfo
printController.printingItem = self.view.toImage()
// If you want to specify a printer
guard let printerURL = URL(string: "Your printer URL here, e.g. ipps://HPDC4A3E0DE24A.local.:443/ipp/print") else { return }
guard let currentPrinter = UIPrinter(url: printerURL) else { return }
printController.print(to: currentPrinter, completionHandler: nil)
printController.presentFromRect(self.view.frame, inView: self.view, animated: true, completionHandler: nil)
}
How to print an UIImage with scale to page for UIPrintInfo in Swift 3?
Finally I found it by myself. I created the uicontrols value by htmlString. And used UIPrintPageRenderer like below mentioned.
class TicketPrintPageRenderer: UIPrintPageRenderer {
let receipt: String
init(receipt: String) {
self.receipt = receipt
super.init()
self.headerHeight = 0.0
self.footerHeight = 0.0 // default
let formatter = UIMarkupTextPrintFormatter(markupText: receipt)
formatter.perPageContentInsets = UIEdgeInsets(top: 2, left: 2,
bottom: 2, right: 2)
addPrintFormatter(formatter, startingAtPageAt: 0)
}
}
Here am creating the controls value to html string like below mentioned:
func createHTMLString(ticketDetail: Ticket, QRImage: UIImage) {
let priceStr = String(format: "$%.02f", ticketDetail.price!)
let storeLogoImage: String = self.getImage(imageName: "storeLogo")
let qrCodeImagePath: String = self.getImage(imageName: "qrCode")
printHtmlString = "<html lang=\"en\"><head><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\"><title>Document</title><style>body {font-family: sans-serif;}.top_Content {text-align: center;padding-top: 10px;}.margin_8 {margin: 8px auto;}.fontstyle_normal {font-weight: normal;}.float_left {float: left;}.float_right {float: right;}.vl {border-left: 2px solid rgb(0, 0, 0);height: 40px;position: absolute;left: 50%;}.container_body{text-align: center;font-weight: normal;}.squareBackground {background-color: rgb(162, 161, 159);width: 100px;height: 100px;}</style></head><body><div><div class=\"top_Content\"><img src=\"file://\(storeLogoImage)\" alt=\"laundryboss_logo\" height=\"100px\"><h3 class=\"margin_8 fontstyle_normal\">\(EmployeeModel.sharedInstance.currentEmployee.employeeSelectedLocation.customerName!)</h3><h4 class=\"margin_8 fontstyle_normal\">\(EmployeeModel.sharedInstance.currentEmployee.employeeSelectedLocation.locationName!)</h4><h3 style=\"width:40%; padding-left: 17px; font-size:1em;\" class=\"float_left margin_8 fontstyle_normal\">Date : \((self.printShareViewModel?.splitDateandTime(createdAt: ticketDetail.ticketDate).createdDate)!)</h3><!-- <span>❘</span> --><div class=\"vl\"></div><h3 style=\"width:40%; padding-right: 17px; font-size:1em;\" class=\"float_right margin_8 fontstyle_normal\">Time : \((self.printShareViewModel?.splitDateandTime(createdAt: ticketDetail.ticketDate).createdTime)!)</h3><h2 style=\"margin: 0;clear: both;padding-top: 14px; font-size:1.2em;\" class=\"fontstyle_normal\">Ticket #\(ticketDetail.ticketNumber!)</h2><h2 style=\"margin: 0;clear: both;padding-top: 14px; font-size:1.2em;\" class=\"fontstyle_normal\">\(ticketDetail.user.name!)</h2><div style=\"display: table;margin: 0 auto;padding-top: 16px;\"><h2 style=\"margin: 0; font-size:1.2em;\" class=\"float_left fontstyle_normal\">Phone :</h2><h3 style=\"margin: 0; font-size:1.2em; padding-left:6px;\" class=\"float_left fontstyle_normal\">\(ticketDetail.user.phone!)</h3></div><p style=\"margin: 0;padding-top: 16px; font-size:1.2em;\">\(ticketDetail.notes!)</p><div style=\"display: table;margin: 0 auto;padding-top: 16px;\"><h2 style=\"margin: 0; font-size:1.2em;\" class=\"float_left fontstyle_normal\">Price :</h2><h3 style=\"margin: 0; font-size:1.2em; padding-left:6px;\" class=\"float_left fontstyle_normal\">\(priceStr)</h3></div><div style=\"margin: 0 auto;display: table; margin-top: 16px;\" class=\"squareBackground\"><!-- <div class=\"squareBackground\"> --><img src=\"file://\(qrCodeImagePath)\" alt=\"Qr_code\" width=\"90\" height=\"90\" align=\"middle\" style=\"padding:5px;\"><!-- </div> --></div></div></div></body></html>"
}
Now When user taps the print button:
@IBAction func act_PrintBtnPressed(_ sender: UIButton) {
let formatter = TicketPrintPageRenderer(receipt: printHtmlString)
let printController = UIPrintInteractionController.shared
printController.showsNumberOfCopies = true
printController.showsPageRange = false
printController.printPageRenderer = formatter
printController.present(animated: true) { (controller, success, errorMsg) in
if success {
print("*************** Print Successfully")
} else {
print("*************** Print Failed : \(errorMsg?.localizedDescription)")
}
}
}
It meets what I excepted.
AirPrint contents of a UIView
I'm not sure if this is the proper way to do it, but I ended up solving this by converting the view to a UIImage
and then setting it as the print controller's printingItem
.
Updated code:
// This is the View I want to print
// Just a 200x200 blue square
var testView = UIView(frame: CGRectMake(0, 0, 200, 200))
testView.backgroundColor = UIColor.blueColor()
let printInfo = UIPrintInfo(dictionary:nil)!
printInfo.outputType = UIPrintInfoOutputType.General
printInfo.jobName = "My Print Job"
// Set up print controller
let printController = UIPrintInteractionController.sharedPrintController()
printController!.printInfo = printInfo
// Assign a UIImage version of my UIView as a printing iten
printController?.printingItem = testView!.toImage()
// Do it
printController!.presentFromRect(self.frame, inView: self, animated: true, completionHandler: nil)
The toImage()
method is an extension to UIView:
extension UIView {
func toImage() -> UIImage {
UIGraphicsBeginImageContextWithOptions(bounds.size, false, UIScreen.mainScreen().scale)
drawViewHierarchyInRect(self.bounds, afterScreenUpdates: true)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
}
Open to alternative approaches if anyone has one!
Related Topics
Run Repeating Nstimer with Gcd
iPhone Collecting Coremotion Data in the Background. (Longer Than 10 Mins)
How to Delete Derived Data and Clean Project in Xcode 5 and Later
Implementing Auto Layout for Views Generated Programmatically
Convert JSON String to JSON Object in Swift 4
Hide Dots from Uipageviewcontroller
Get Email and Name Facebook Sdk V4.4.0 Swift
Swift Regex: Does a String Match a Pattern
When Will Applicationwillterminate Be Called
iOS 11 Core Nfc - Any Sample Code
Swift 2.0 Minimum System Version Requirement (Deployment Target)
Use Uibarbuttonitem Icon in Uibutton
App Submission Binary Does Not Show Up in Itunes Connect
Expand and Collapse Tableview Cells
iOS Keychain Services: Only Specific Values Allowed for Ksecattrgeneric Key