この記事は リクルートライフスタイル Advent Calendar 2017 の3日目の記事です。
はじめに
ホットペッパービューティーでアプリの開発を担当してる@sotozakiです。
最近は資料を作る機会も増えてきました。
iOSエンジニアだったら、普段書いてるSwiftでプレゼン資料も作りたいはず(?)
今回はSwiftでプレゼン資料を作ってみます!
環境
バージョン | |
---|---|
Swift | 4.0 |
Xcode | 9.1 |
完成したもの
このようなPDFの資料を作ることが出来ます。
プレゼン資料の作り方
PDFKitを使ってPDFを出力することでプレゼン資料を作ります。
今年のWWDCでもPDFKitが取り上げられ、MacOSのみだったものがiOSにも対応しました。
- https://developer.apple.com/documentation/pdfkit
- https://developer.apple.com/videos/play/wwdc2017/241/
PDFKit
PDFKitのPDFViewというClassを利用することでPDFViewerのようなアプリは簡単に実装することができるようになりました。
今回はViewerではなくプレゼン資料としてPDFを出力したいため、PDFDocument, PDFPageといたClassを利用していきます。
PDFDocument, PDFPage
Swift PlayGroundで書いていきます。
まずはPDFKitをimportします。
import PDFKit
PDFPageを継承したクラスを作成し、iOSエンジニア(の一部)には馴染みのあるdrawメソッドをoverrideして文字や線を描画しています。
final class SamplePage: PDFPage {
private let width = 1024
private let height = 768
private let title: String
private let contents: String
init(title: String, contents: String) {
self.title = title
self.contents = contents
super.init()
}
override func draw(with box: PDFDisplayBox, to context: CGContext) {
super.draw(with: box, to: context)
UIGraphicsPushContext(context)
context.translateBy(x: 0.0, y: CGFloat(height))
context.scaleBy(x: 1.0, y: -1.0)
let rect = CGRect(x: 25, y: 25, width: width, height: 100)
let attributes = [NSAttributedStringKey.font: UIFont.systemFont(ofSize: 50),
NSAttributedStringKey.foregroundColor: UIColor.black]
title.draw(in: rect, withAttributes: attributes)
let rect2 = CGRect(x: 25, y: 200, width: width, height: 600)
contents.draw(in: rect2, withAttributes: attributes)
let path = UIBezierPath()
path.move(to: CGPoint(x: 0, y: 100))
path.addLine(to: CGPoint(x: width, y: 100))
path.lineWidth = 5.0
path.stroke()
UIGraphicsPopContext()
}
override func bounds(for box: PDFDisplayBox) -> CGRect {
return CGRect(x: 0, y: 0, width: width, height: height)
}
}
あとはPDFDocumetクラスのインスタンスにPDFPageをinsertしていけば良いです。
let pdf = PDFDocument()
let contents = """
・ここにコンテンツを入力します。
"""
let firstPage = SamplePage(title: "タイトル", contents:contents)
pdf.insert(firstPage, at: 0)
複数ページ作成する時は同様にinsertを複数回呼ぶとできます。
ここまででpdfの準備はできました。
最後にファイルに書き出します。
if let url = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {
let path = url.appendingPathComponent("output.pdf")
print(path)
pdf.write(to: path)
}
出力されたpathにPDFが出力されます 🎉
最後に
PDFKitを利用することで、簡単にSwiftでPDF資料を作ることができました!
テーマに対応したり、他のレイアウトでも作れるようになると本格的にSwiftで資料作ることが出来るようになりますね。
最後にソースコードを載せておきます!
ソースコード
import UIKit
import PDFKit
final class SamplePage: PDFPage {
private let width = 1024
private let height = 768
private let title: String
private let contents: String
init(title: String, contents: String) {
self.title = title
self.contents = contents
super.init()
}
override func draw(with box: PDFDisplayBox, to context: CGContext) {
super.draw(with: box, to: context)
UIGraphicsPushContext(context)
context.translateBy(x: 0.0, y: CGFloat(height))
context.scaleBy(x: 1.0, y: -1.0)
let rect = CGRect(x: 25, y: 25, width: width, height: 100)
let attributes = [NSAttributedStringKey.font: UIFont.systemFont(ofSize: 50),
NSAttributedStringKey.foregroundColor: UIColor.black]
title.draw(in: rect, withAttributes: attributes)
let rect2 = CGRect(x: 25, y: 200, width: width, height: 600)
contents.draw(in: rect2, withAttributes: attributes)
let path = UIBezierPath()
path.move(to: CGPoint(x: 0, y: 100))
path.addLine(to: CGPoint(x: width, y: 100))
path.lineWidth = 5.0
path.stroke()
UIGraphicsPopContext()
}
override func bounds(for box: PDFDisplayBox) -> CGRect {
return CGRect(x: 0, y: 0, width: width, height: height)
}
}
let pdf = PDFDocument()
let contents = """
・PDFKitをimportする。
・PDFPageのdrawをoverrideする。
・PDFDocumentにPDFPageをinsertする。
・PDFDocumentをファイル書き出し。
"""
let firstPage = SamplePage(title: "【PDFKit】Swiftでプレゼン資料を作る", contents:contents)
pdf.insert(firstPage, at: 0)
if let url = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {
let path = url.appendingPathComponent("output.pdf")
print(path)
pdf.write(to: path)
}