質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

2回答

807閲覧

pdfの合成の仕方が分からない

mimamo

総合スコア44

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2019/01/12 02:10

編集2019/01/17 03:36

前提・実現したいこと

イメージ説明

画像のように、PDFとPDFをくっつけてひとつのPDFにし、それをiPhone画面で確認できるようにした後、印刷できるようにしたいです。
ですが、どのようにPDFとPDFをくっつければいいのかわかりません。

左側はアプリ内でローカル保存したPDF。
右側はアプリ内にあらかじめ取り込んだPDFです。

あと、できれば真ん中に点線を入れたいです。

考え方など、ご教授よろしくお願いいたします。

該当のソースコード

ローカル保存するVC

Swift

1@IBAction func push(_ sender: Any) { 2 print("push") 3 4 5 let pdfData = NSMutableData() 6 UIGraphicsBeginPDFContextToData(pdfData, self.view.bounds, nil) 7 UIGraphicsBeginPDFPage() 8 9 guard let pdfContext = UIGraphicsGetCurrentContext() else { return } 10 self.view.layer.render(in: pdfContext) 11 UIGraphicsEndPDFContext() 12 13 if let documentDirectories = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first { 14 let documentsFileName = documentDirectories + "/test.pdf" 15 UserDefaults.standard.set(documentsFileName, forKey:"filePath") 16 debugPrint(documentsFileName) 17 pdfData.write(toFile: documentsFileName, atomically: true) 18 } 19 20 }

PDFとPDFを合成したいVC

Swift

1 2import UIKit 3import PDFKit 4 5class PhotoT: UIViewController { 6 7///A4+A4 8 9 10 @IBOutlet weak var left: UIImageView! 11 @IBOutlet weak var right: UIImageView! 12 13 override func viewDidLoad() { 14 super.viewDidLoad() 15 16 17 // プロジェクトにあらかじめ取り込んでおいたPDFの読み込み (右側に配置したいPDF) 18 let binsenhoge = UserDefaults.standard.integer(forKey: "selectedTag") 19 let binsenpath: String = Bundle.main.path(forResource: "huto(binsenhoge)", ofType: "pdf")! 20 print("くっつけるのは") 21 print(binsenpath) 22 23 24 drawPDFfromURL(url: binsenpath) 25 26 27 28 } 29 30 31 func drawPDFfromURL(url: URL) -> UIImage? { 32 33 34 guard let document = CGPDFDocument(url as CFURL) else { return nil } 35 guard let page = document.page(at: 1) else { return nil } 36 37 let pageRect = page.getBoxRect(.mediaBox) 38 let renderer = UIGraphicsImageRenderer(size: pageRect.size) 39 let img = renderer.image { ctx in 40 UIColor.white.set() 41 ctx.fill(pageRect) 42 43 ctx.cgContext.translateBy(x: 0.0, y: pageRect.size.height) 44 ctx.cgContext.scaleBy(x: 1.0, y: -1.0) 45 46 ctx.cgContext.drawPDFPage(page) 47 } 48 49 return img 50 } 51 52

##エラー

swift

1drawPDFfromURL(url: binpath)

Cannot convert value of type 'String' to expected argument type 'URL'

###アドバイスを受けて

該当のファイルを表示させることができるようになりました。

ですが不具合が起きています。
保存したPDFを確認すると上に余白はほとんどない状態なのですが、UIImageView(aspect fit)で表示すると下のように表示されてしまいます。

ローカルPDF保存したPDFを表示

PDFとしてローカル保存した際のコード

Swift

1 @IBAction func push(_ sender: Any) { 2 print("push") 3 4 5 let x = getimage.frame.origin.x 6 let y = getimage.frame.origin.y 7 //UIImageView(getimage)のサイズ取得 8 let imageWidth = self.getimage.frame.width 9 let imageHeight = self.getimage.frame.height 10 11 12 let pdfData = NSMutableData() 13 // ↓ -yとすることでNavigationbarとステータスバーの下からPDFを保存することができました 14 UIGraphicsBeginPDFContextToData(pdfData, CGRect(x: x, y: -y, width: imageWidth, height: imageHeight), nil) 15 UIGraphicsBeginPDFPage() 16 17 guard let pdfContext = UIGraphicsGetCurrentContext() else { return } 18 self.view.layer.render(in: pdfContext) 19 UIGraphicsEndPDFContext() 20 21 if let documentDirectories = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first { 22 let documentsFileName = documentDirectories + "/test.pdf" 23 UserDefaults.standard.set(documentsFileName, forKey:"filePath") 24 debugPrint(documentsFileName) 25 pdfData.write(toFile: documentsFileName, atomically: true) 26 } 27 28 } 29 30

clip to Bounds

イメージ説明

補足情報(FW/ツールのバージョンなど)

Swiftのversionは4.1.2
Xcodeのversionは9.4.1

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hameji001

2019/01/12 09:59

おそらくですが、印刷を想定していますし、 それにはまずサイズを指定しないといけないのではないでしょうか? A4, B4とかですか?
mimamo

2019/01/12 15:48

AirprintだとpdfはA4で印刷されるみたいなので、A5サイズ(右側のpdf)とA5サイズ(左側のpdf)をくっつけたA4で印刷したいと思っています。
guest

回答2

0

ベストアンサー

英語のサイトになりますが、PDF -> UIImageViewの変換が書いてあるので、

https://www.hackingwithswift.com/example-code/core-graphics/how-to-render-a-pdf-to-an-image

これを利用して、UIImageView、UIImageViewに並べて表示して、
間の点線もUIImageで用意して、合わせた後、
再度PDFに変換すればいいのではないでしょうか?

投稿2019/01/14 23:35

hameji001

総合スコア639

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mimamo

2019/01/15 14:21 編集

お返事遅くなりすみません。ご回答ありがとうございます! PDFからUIImageViewに変換することができるのですね!  そのやり方でやってみようと思いコーディングしてみたのですが理解が進まず、またエラーも出てしまいました、、。 質問本文のコードを変更させていただきました。 ご教授お願いいたします。
hameji001

2019/01/15 16:01 編集

参照HPのコードのとこ、URLをファイルパスに置き換えるだけで、 簡単に表示できましたが、、、 Xcodeのプロジェクト内にpdfファイルを起き、 single viewにUIImageとUIButtonをstoryboardで配置し、 ボタンを押したタイミングで、UIImageにimageをセットするだけですよ。 mimamoさんのコードのように最初からでもいいですが。 コードを見ると、間違えてるとこがわかりました。 func drawPDFfromURL(url: URL) -> UIImage? {}の 「-> UIImage?」 の意味をよく考えてください。 つまり「返り値 swift」と検索して、勉強してみてください。 また、func 内の最後にあるreturnが何を意味してるかも考えてくださいね。 https://dev.classmethod.jp/smartphone/swift-function-tuple/ 今後も、この考え方は必要で大事ですから。 勉強して、身につけてくださいね。
mimamo

2019/01/15 18:53

ありがとうございます。返り値がUIImage型で出力されるということなのでUIImageとして扱ってみたのですが同様のエラーが出てしまいました。 変更点 ``` var image1:UIImage! ←追加 override func viewDidLoad() { super.viewDidLoad() image1 = drawPDFfromURL(url: binpath) ←変更 right.image = image1 } ```
hameji001

2019/01/15 23:19 編集

自分の時は問題なくできましたよ。 疑わしいのはurlだと思います。 mimamoさんのurlの中身がわかりませんが、 自分は"test.pdf"というファイルをプロジェクトに含めたなら、 let pdfName = "test.pdf" let url = Bundle.main.bundleURL.appendingPathComponent(pdfName) で表示されましたよ。 ちなみに、直接 right.image = drawPDFfromURL(url: XXXXX)で大丈夫ですよ。
mimamo

2019/01/16 02:05

ありがとうございます。ファイル名を直接入力しちゃってよかったのですね。 右左、どちらも表示させることができました! なのですが、ローカル保存したPDFがおかしい感じで表示されています。これはなにが原因なのでしょうか、、ご教授よろしくお願いします。
hameji001

2019/01/16 05:24 編集

オフセットされているので、 故意的にずらせばいいのではないでしょうか? 「swift view オフセット」で検索を。
mimamo

2019/01/16 07:39

ありがとうございます。 オフセットされているということですが、ローカル保存したPDFがUIimageviewに表示される時にオフセットされているということでしょうか。
hameji001

2019/01/16 08:25

きっとそういう仕様?なのかと思います。 自分の時もそうなってました。
mimamo

2019/01/16 12:33

ありがとうございます。 以下のようにコーディングしてみました。 @IBOutlet weak var left: UIImageView! @IBOutlet weak var right: UIImageView! var Imagerect: CGRect override func viewDidLoad() { super.viewDidLoad() // プロジェクトにあらかじめ取り込んでおいたPDFの読み込み (右側に配置したい) let binhoge = UserDefaults.standard.integer(forKey: "selectedTag") let rightpdfName = "huto(binhoge).pdf" let righturl = Bundle.main.bundleURL.appendingPathComponent(rightpdfName) print("右側のPDF") right.image = drawPDFfromURL(url: righturl) right.frame = CGRect.offsetBy(0,64) ←追加コード オフセット? // 作成したローカルPDFの読み込み let filePath0 = UserDefaults.standard.string(forKey:"filePath") let leftpdfURL = URL(fileURLWithPath: filePath0!) print("左側のPDF") left.image = drawPDFfromURL(url: leftpdfURL) } オフセットらしきコードをつけた後、 Instance member 'offsetBy' cannot be used on type 'CGRect'; did you mean to use a value of this type instead? というエラーが発生してしまいました。
mimamo

2019/01/17 03:35

ありがとうございます。 storyboardで、clip to Boundsにチェックをいれ、contentModeをTop Leftにしたら上の画像のようになってしまいました。
hameji001

2019/01/17 04:29 編集

あとは、imageviewの表示の仕方だけです。本題とはそれますし、 自分のプログラムですし、言われたことだけをするのではなく、 自分で調べたり工夫してください。 自分もそうですが、trial and errorの精神が大事です。 https://teratail.com/questions/166765#reply-250343 この時と似たようなことじゃないんですか?
mimamo

2019/01/17 14:40

ありがとうございます。 そうですね、、本題とはだいぶ逸れてしまっていますね、すみません。 以前ご回答頂いたものをきっかけに、どこか数値をいじれるとこがあるのではないかと思いいろいろいじってみました。 func drawPDFfromURL(url: URL) -> UIImage? { ctx.cgContext.translateBy(x: 0.0, y: pageRect.size.height) } のpageRect.size.heightを変えることで表示したいように表示できました。 ありがとうございました!
hameji001

2019/01/17 15:11 編集

お疲れ様でした。 imageViewは自分のアプリではあまり使用してないので、勉強になります。 お互いアプリ公開に向けて、頑張りましょう! 多少強引なプログラミングでも、まずは公開にたどり着くことが大事ですよね。
mimamo

2019/01/21 14:15

そうですね! お互い頑張りましょう!!
guest

0

きちんとA4で印刷できるかどうかはわかりませんが、
SwiftでUIViewを簡単にPDFで保存できるライブラリがあります

GitHub sgr-ksmt / PDFGenerator

Viewに並べて表示したPDFを合成できるかどうかはわかりませんが、
このライブラリは、たいていのUIVIewはきれいに保存してくれるので、
試してみる価値はあると思います。

投稿2019/01/14 17:11

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mimamo

2019/01/15 14:19

お返事遅くなりすみません。 ご回答ありがとうございます! 質問がわかりづらくて申し訳ないです。 UIViewをPDFに保存することはできたのですが、その保存したPDFを別の既存のPDFとくっつけて保存したいなと思っています。
退会済みユーザー

退会済みユーザー

2019/01/15 15:24

このライブラリはUIView全体をPDFに変換するもので、 画面にPDFを2つ同時に表示すると、その状態をPDFに変換できるのでは、 という意味で回答しました。
mimamo

2019/01/15 19:06

ありがとうございます! ひとまず、PDFをふたつ表示させる必要があるということですね、、 質問本文のように、今PDFを2つ表示させる方法にトライしています。
退会済みユーザー

退会済みユーザー

2019/01/15 23:44

PDFはUIWebViewで表示すると簡単ですし、テキストデータもそのまま選択できるようになります。 また、そのUIWebViewをPDFGeneratorで保存すると、テキスト選択できるPDFになるので、容量削減や使い勝手などで利点があります。 このページがとても参考になると思います。 【swift】ライブラリを使ってhtmlをpdfデータとして保存しwebViewで表示&動的に書き換える https://qiita.com/narukun/items/8c78eae6c9b393d20782
mimamo

2019/01/16 02:09

ありがとうございます。文字が入っていると格段に使いやすさを実感できそうですね! htmlからPDFを使う際はこちらをトライしてみようと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問