Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
9
Help us understand the problem. What is going on with this article?
@keita1987

WKWebViewにHTML表示させ、PDF化する(Swift2.2, XCode7.3.1)

More than 3 years have passed since last update.

業務でHTMLファイルをPDF化する必要があったのでメモしておきます。

画面

スクリーンショット 2016-05-19 12.22.14.jpg
スクリーンショット 2016-05-19 12.22.26.jpg

コード

import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate, UIScrollViewDelegate {
    private var subView: UIView!
    private var webView: WKWebView!

    override func viewDidLoad()
    {
        super.viewDidLoad()

        let size = view.frame.size
        subView = UIView(frame: CGRectMake(0, 0, size.width, size.height - 50))

        let btn = UIButton(type: .System)
        btn.frame = CGRectMake(0, size.height - 50, 90, 40)
        btn.setTitle("set HTML", forState: .Normal)
        btn.addTarget(self, action: #selector(ViewController.tapBtn(_:)), forControlEvents: .TouchUpInside)

        let btn2 = UIButton(type: .System)
        btn2.frame = CGRectMake(size.width * 0.35, size.height - 50, 90, 40)
        btn2.setTitle("set from web", forState: .Normal)
        btn2.addTarget(self, action: #selector(ViewController.tapBtn2(_:)), forControlEvents: .TouchUpInside)

        let btn3 = UIButton(type: .System)
        btn3.frame = CGRectMake(size.width * 0.7, size.height - 50, 90, 40)
        btn3.setTitle("create pdf", forState: .Normal)
        btn3.addTarget(self, action: #selector(ViewController.tapBtn3(_:)), forControlEvents: .TouchUpInside)

        view.addSubview(subView)
        view.addSubview(btn)
        view.addSubview(btn2)
        view.addSubview(btn3)

        webView = WKWebView()
        setupSubViews(subView)
    }

    internal func tapBtn(sender: UIButton) {
//        webView.loadHTMLString(getStrFromFile("test.html"), baseURL: nil)
        webView.loadHTMLString("hoge<br>piyo<br>foo<br>bar<br>hogeeeeeeeeeeeeeeeee", baseURL: nil)
    }

    internal func tapBtn2(sender: UIButton) {
        let req = NSURLRequest(URL: NSURL(string:"http://www.yahoo.co.jp/")!)
        webView.loadRequest(req)
    }

    internal func tapBtn3(sender: UIButton) {
        let path = NSHomeDirectory().stringByAppendingString("/hoge.pdf")
        PDFMaker.make([webView], path: path)
    }


    private func setupSubViews(v: UIView)
    {
//        webView.navigationDelegate = self
//        webView.scrollView.delegate = self
        webView.translatesAutoresizingMaskIntoConstraints = false
        v.addSubview(webView)
        var viewBindingsDict = [String: AnyObject]()
        viewBindingsDict["webView"] = webView
        v.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[webView]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: viewBindingsDict))
        v.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[webView]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: viewBindingsDict))
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // プロジェクトに追加したローカルファイルの文字列取得
    private func getStrFromFile(fname: String) -> String {
        var ret = ""
        var path = NSString(string: fname)
        // Encode 日本語ファイル対応
        path = path.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!
        let ext = path.pathExtension
        let filename = path.stringByDeletingPathExtension
        do {
            if let path = NSBundle.mainBundle().pathForResource(filename, ofType: ext) {
                ret = try String(contentsOfFile: path, encoding: NSUTF8StringEncoding)
            }
        } catch {
            print("error getStrFromFile")
        }
        return ret
    }
}

// PDF作成クラス
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
    }
}

作成したPDFを探す

シミュレータの場合

➜  ~ find ~/Library/Developer/CoreSimulator/Devices -name "hoge.pdf"
9
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
keita1987
プログラマです。 業務系アプリ作ってます。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
9
Help us understand the problem. What is going on with this article?