最近在作的一個iOS項目有個打印 pdf的功能。查找資料發現蘋果早在 iOS 4.2 就有了 AirPrint 功能。網上關於AirPrint 的資料很少,因此就寫了這篇博文。 下面就和你們分享一下本身的學習收穫。html
an array of ready-to-print images and PDF documents: 一組圖片文件和PDF文件。swift
a single image or PDF document: 一張圖片或是一個pdf文件。、api
an instance of any of the built-in print formatter classes: 打印格式化者的實例。(簡單文本,html文檔,某些View顯示的內容)。bash
a custom page renderer: 自定義頁渲染者。 註釋: 1,2 很簡單,就不詳細解釋了,3,4姑且這樣翻譯了,不懂不要緊, 繼續向下看。。。app
UIPrintInfo *printInfo: 打印任務的信息。dom
UIPrintPaper * printPaper : 打印內容的區域。iphone
delegate: 遵照UIPrintInteractionControllerDelegate 協議的代理。學習
最重要的就是制定須要打印的內容: printingItem , printingItems, printFormatter, printPageRenderer。 四個屬性都是用來指定要打印的內容的。 這四個參數是互斥的, 也就是說只要一個賦值, 其餘三個參數就得是nil. 很容易理解,一個打印任務, 不能同時幹多個活呀。 這裏若是使用 swift的枚舉,就很容易理解了。 這裏提到的四個關於內容的屬性, 和 第4 點是關聯起來的。 下面這張表是對應關係: 測試
建立 UIPrintInteractionController 實例。ui
建立UIPrintInfo 實例。 並 配置參數 output type(輸出類型), print orientation(打印方向), job name(打印工做標識), 而後賦值給UIPrintInteractionController 實例的 printInfo屬性。
給delegate 屬性賦值, 賦的值必須遵照 UIPrintInteractionControllerDelegate 協議。 這個代理能夠 響應 printing options界面的顯示和消失, 打印工做的開始和結束 等。
指定要打印的內容。 也就是指定 printingItem , printingItems, printFormatter, printPageRenderer. 參數的其中一個。
當你使用 printPageRenderer. 時狀況會複雜一些。 你能夠繪製每一頁的header, footer, 內容。 這是你須要本身計算頁數。 另外, 你也能夠建立一個或多個 UIPrintFormatter實例, 經過 addPrintFormatter:startingAtPageAtIndex: 或者 printFormatters參數 賦值給 printPageRenderer.實例。 這種狀況下不須要本身計算多少頁。
最後就是顯示顯示出printing options 界面了。 方法: 在iPad上: presentFromBarButtonItem:animated:completionHandler: 或者 presentFromRect:inView:animated:completionHandler:; 在手機上: presentAnimated:completionHandler:
AirPrint能夠直接打印一些內容。 這些內容是 NSData, NSURL, UIImage, and ALAsset 類的實例, 可是這些實例的內容, 或者引用的類型(NSURL)必須是 image 或者pdf.
對於 image來講, NSData, NSURL, UIImage, and ALAsset 類型均可以的。 對於PDF, 只能使用 NSData, NSURL。 而後須要將這些數據實例直接賦值 給 UIPrintInteractionController實例的 printingItem 或者 printingItems 屬性。
打印pdf:
- (IBAction)printContent:(id)sender {
UIPrintInteractionController *pic = [UIPrintInteractionController sharedPrintController];
if (pic && [UIPrintInteractionController canPrintData: self.myPDFData] ) {
pic.delegate = self;
UIPrintInfo *printInfo = [UIPrintInfo printInfo];
printInfo.outputType = UIPrintInfoOutputGeneral;
printInfo.jobName = [self.path lastPathComponent];
printInfo.duplex = UIPrintInfoDuplexLongEdge;
pic.printInfo = printInfo;
pic.showsPageRange = YES;
pic.printingItem = self.myPDFData;
void (^completionHandler)(UIPrintInteractionController *, BOOL, NSError *) =
^(UIPrintInteractionController *pic, BOOL completed, NSError *error) {
self.content = nil;
if (!completed && error)
NSLog(@"FAILED! due to error in domain %@ with error code %u",
error.domain, error.code);
};
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
[pic presentFromBarButtonItem:self.printButton animated:YES
completionHandler:completionHandler];
} else {
[pic presentAnimated:YES completionHandler:completionHandler];
}
}
複製代碼
系統提供了三個 Print Formatters類, 分別是:
UIViewPrintFormatter—automatically lays out the content of a view over multiple pages. To obtain a print formatter for a view, call the view’s viewPrintFormatter method. Not all built-in UIKit classes support printing. Currently, only the view classes UIWebView, UITextView, and MKMapView know how to draw their contents for printing. View formatters should not be used for printing your own custom views. To print the contents of a custom view, use a UIPrintPageRenderer instead.
UISimpleTextPrintFormatter—automatically draws and lays out plain-text documents. This formatter allows you to set global properties for the text, such a font, color, alignment, and line-break mode.
UIMarkupTextPrintFormatter—automatically draws and lays out HTML documents.
- (IBAction)printContent:(id)sender {
UIPrintInteractionController *pic = [UIPrintInteractionController sharedPrintController];
pic.delegate = self;
UIPrintInfo *printInfo = [UIPrintInfo printInfo];
printInfo.outputType = UIPrintInfoOutputGeneral;
printInfo.jobName = self.documentName;
pic.printInfo = printInfo;
UIMarkupTextPrintFormatter *htmlFormatter = [[UIMarkupTextPrintFormatter alloc]
initWithMarkupText:self.htmlString];
htmlFormatter.startPage = 0;
htmlFormatter.contentInsets = UIEdgeInsetsMake(72.0, 72.0, 72.0, 72.0); // 1 inch margins
pic.printFormatter = htmlFormatter;
pic.showsPageRange = YES;
void (^completionHandler)(UIPrintInteractionController *, BOOL, NSError *) =
^(UIPrintInteractionController *printController, BOOL completed, NSError *error) {
if (!completed && error) {
NSLog(@"Printing could not complete because of error: %@", error);
}
};
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
[pic presentFromBarButtonItem:sender animated:YES completionHandler:completionHandler];
} else {
[pic presentAnimated:YES completionHandler:completionHandler];
}
}
複製代碼
- (void)printWebPage:(id)sender {
UIPrintInteractionController *controller = [UIPrintInteractionController sharedPrintController];
void (^completionHandler)(UIPrintInteractionController *, BOOL, NSError *) =
^(UIPrintInteractionController *printController, BOOL completed, NSError *error) {
if(!completed && error){
NSLog(@"FAILED! due to error in domain %@ with error code %u",
error.domain, error.code);
}
};
UIPrintInfo *printInfo = [UIPrintInfo printInfo];
printInfo.outputType = UIPrintInfoOutputGeneral;
printInfo.jobName = [urlField text];
printInfo.duplex = UIPrintInfoDuplexLongEdge;
controller.printInfo = printInfo;
controller.showsPageRange = YES;
UIViewPrintFormatter *viewFormatter = [self.myWebView viewPrintFormatter];
viewFormatter.startPage = 0;
controller.printFormatter = viewFormatter;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
[controller presentFromBarButtonItem:printButton animated:YES completionHandler:completionHandler];
}else
[controller presentAnimated:YES completionHandler:completionHandler];
}
複製代碼
這部份內容是最複雜的了, 感受不怎麼用,暫且不深究了, 你們若是項目須要, 本身看文檔吧。
到這裏,我學習到的 AirPrint的主要技術點已經和你們分享完了。基本能夠搞定大部分的需求。 若是那裏說錯了, 很是歡迎你們能給提出。 另外剛開始寫技術博客, 經驗不足, 但願你們多提寶貴意見。