2016年09月29日

[iOS] 印刷

iOS担当のエモトです.先日「聲の形」を見ました.京アニさん流石ですのクオリティの高さに加え,人間の無知で無垢な強暴性から始まる己自身やお互いの葛藤,そして最終局面への展開からは目が離せなませんでした.円盤買います.ぼくは植野推しです.今晩は「君の名は」を見に行きます.是が非でも定時に帰ります.

iOS端末からプリンターで印刷するには,iOS4.2で実装された UIPrintInteractionController を用いれば,印刷設定を含め印刷を行うことができます(いわゆるAirPrint).さらにiOS8から UIPrinterPickerController が追加され,プリンター選択を別にできるようになりました.

1. 始める前に

テストのたびに実際に印刷が行われていると大変,そもそもAirPrint対応のプリンターが手元にない場合,Printer Simulatorを入れておくと仮想プリンターとして印刷結果も確認できるので便利です.Printer Simulatorはアップルの ディベロッパーサイト からHardware IO Tools for Xcode (またはAdditional Tools for Xcode)を選び,ダウンロードすることができます.

2. UIPrintInteractionControllerで印刷する

UIPrintInteractionControllerの使い方は非常に簡単で,以下の通りのコードを書けば印刷することができます.例では画像を印刷しています.
let pic = UIPrintInteractionController.sharedPrintController()
pic.printingItem = UIImage(named: "hogehoge")
let completion:UIPrintInteractionCompletionHandler = { (controller, completed, error) in
    print("completed = \(completed), error = \(error)")
}
pic.presentAnimated(true, completionHandler: completion)
とはいえこれは色々と支障がでるので,端末やprintingItemが印刷可能かどうか判定する処理を追加します.ここで,canPrintの初期値をtrueにしているので,印刷可能か判定するメソッドがNSDataとNSURLを対象にしているのに対して,前述のように直接的画像データを指定できるためです.判定を網羅できなていないです.
let obj = printingItem
var canPrint:Bool = true
if obj.isKindOfClass(NSData) {
    canPrint = UIPrintInteractionController.canPrintData(obj as! NSData)
}else if obj.isKindOfClass(NSURL){
    canPrint = UIPrintInteractionController.canPrintURL(obj as! NSURL)
}
if UIPrintInteractionController.isPrintingAvailable() && canPrint {
    // ...略
}
印刷可能のものは,画像のほかに viewPrintFormatter メソッドをもつUIViewを継承したインスタンスも可能となっています
pic.printingItem = view.viewPrintFormatter()
しかしながら,viewPrintFormatterがうまく生成されない場合が多く,viewを対象とする場合は手を加えないといけません.

(a) 画像もしくはPDFに変換する
stack overflowなどを覗くとみなさん同じ悩みのようでした.ちょっと乱暴な処理ですが,画像化などで切り抜けましょう.しかし,スクロールやページングがあったらどうすればいいんだろ・・・
UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, 0.0);
view.drawViewHierarchyInRect(view.bounds, afterScreenUpdates: false)
let image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
pic.printingItem = image
(b) printPageRendererを設定する
これはアップルの サンプルコード PrintWebView を拝借しました.コード内のAPLPrintPageRendererを使って,以下のようにprintPageRendererを設定します.これにより,viewの印刷ができますが,上手くいくのはUIWebViewなどのようです.
let viewPrintFormatter = view.viewPrintFormatter();
let renderer = APLPrintPageRenderer();
renderer.jobTitle = info.jobName
renderer.addPrintFormatter(viewPrintFormatter, startingAtPageAtIndex: 0)
pic.printPageRenderer = renderer;

3. UIPrinterPickerControllerでプリンター選択

UIPrinterPickerControllerを使えば,前述のUIPrintInteractionControllerからプリンター選択を独立させることができます.機能差は少ないですが,プリント設定画面のスキップや自作が可能になります.
var printer:UIPrinter? = nil

func selectPrinter(){
    let ppc = UIPrinterPickerController(initiallySelectedPrinter: nil)
    ppc.presentAnimated(true, completionHandler: {
        (printerPickerController, userDidSelect, error) in
            if error == nil {
                if let printer = printerPickerController.selectedPrinter{
                    self.printer = printer
                }
            }else{
                print("error = \(error)")
            }
        })
}

func printObject(){
    // その他設定は省略
    pic.printToPrinter(self.printer, completionHandler: completion)
}
posted by Seesaa京都スタッフ at 12:00| Comment(0) | iOS | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント: