UIViewをPDFファイルに変換する

Tuesday, February 2, 2016

Objective-Cで、UIImage複数枚→PDF ファイル生成をやったのですが、
それをSwiftで書き直すぞってなって、ひとまず UIView を複数なげてpdfを生成するクラスを作ってみました。
初めてUIGraphicsBeginPDF〜〜系を使いました!

コードはこんな感じです。

class PDFMaker {

    private class func renderViews(views: [UIView]) {
        guard let context = UIGraphicsGetCurrentContext() else {
            return
        }
        views.forEach {
            if let scrollView = $0 as? UIScrollView {
                let tmpInfo = (offset: scrollView.contentOffset, frame: scrollView.frame)
                scrollView.contentOffset = CGPointZero
                scrollView.frame = CGRect(origin: CGPointZero, size: scrollView.contentSize)
                UIGraphicsBeginPDFPageWithInfo(scrollView.frame, nil)
                $0.layer.renderInContext(context)
                scrollView.frame = tmpInfo.frame
                scrollView.contentOffset = tmpInfo.offset
            } else {
                UIGraphicsBeginPDFPageWithInfo($0.bounds, nil)
                $0.layer.renderInContext(context)
            }
        }
    }

    class func make(views: [UIView], path: String) {
        UIGraphicsBeginPDFContextToFile(path, CGRectZero, nil)
        renderViews(views)
        UIGraphicsEndPDFContext()
    }

    class func make(views: [UIView]) -> NSData {
        let data = NSMutableData()
        UIGraphicsBeginPDFContextToData(data, CGRectZero, nil)
        renderViews(views)
        UIGraphicsEndPDFContext()
        return data
    }

}

一応、 UIScrollView (のサブクラス含めて)も考慮しています。 これで、 UIView を投げて、PDFのデータ(NSData)を取得するか、 path を指定して、そこにPDFを生成する事ができます。
上記実装して、以下のようにすれば、アプリのルートディレクトリに、
赤緑青の3枚のviewからなる sample.pdf というPDFが生成されます。

let v1 = UIScrollView(frame: CGRectMake(0,0,100,100))
let v2 = UIView(frame: CGRectMake(0,0,100,300))
let v3 = UIView(frame: CGRectMake(0,0,100,300))
v1.backgroundColor = UIColor.redColor()
v1.contentSize = CGSize(width: 100, height: 300)
v2.backgroundColor = UIColor.greenColor()
v3.backgroundColor = UIColor.blueColor()

let dst = NSHomeDirectory().stringByAppendingString("/hoge.pdf")
PDFMaker.make([v1, v2, v3], path: dst)


後日、UIImageの配列を投げるverと、メモリを考慮して、UIImageのfullPathの配列を投げてPDFを生成するパターンも作成して、ライブラリ化しようと思います。
あとは思いつきですが、UIScrollViewと、区切るsizeを指定してPDF化できたらいいんじゃないかなとか思ったり。
ひとまずは。

参考

techiOSSwift

carthage archiveでのzipの出力先を変える

Hugoで下書き状態のmarkdownをチェックするshellスクリプト