Core Locationでジオフェンシングを実装した後、アプリ内でPDF資料を表示したいと考え、PDFKitによるPDF表示・注釈機能に挑戦しました。
1. 表示だけならすぐ終わると思っていた
最初、PDFViewにファイルを渡すだけで、あとは何もしなくても実用的なビューアになると思い込んでいました。
let pdfView = PDFView()
pdfView.document = PDFDocument(url: fileURL)
このコードだけでも表示自体はできるのですが、ピンチズームの挙動が不自然だったり、ページ送りのスクロールが期待通りに動かなかったりしました。調べてみると、autoScalesやdisplayModeなどのプロパティを目的に応じて設定しないと、実用的な閲覧体験にはならないことが分かりました。
2. 全ページのサムネイルを一度に生成して固まった
ページ一覧をサムネイルで表示する機能を作ろうとして、ドキュメントの全ページを一度にまとめて画像化する処理を書いていました。
let page = pdfDocument.page(at: index)
let thumbnail = page.thumbnail(of: size, for: .mediaBox)
ページ数が多いPDFで試したところ、アプリの応答が止まってしまいました。サムネイル生成は見た目以上に処理が重く、全ページを同期的にまとめて処理するとメインスレッドが長時間ブロックされることが原因でした。表示に必要な範囲だけを都度生成する、あるいはバックグラウンドで処理する方式に変更する必要がありました。
3. 注釈を追加しても保存されず消えてしまった
ユーザーがPDF上にハイライトなどの注釈を追加できる機能を実装したものの、アプリを再起動すると注釈がすべて消えてしまう現象に悩まされました。
pdfDocument.write(to: fileURL)
PDFAnnotationを追加しただけではメモリ上のドキュメントが変更されるだけで、ファイルへの反映は明示的にwrite(to:)を呼ばない限り行われないことが分かりました。この保存処理を呼び忘れていたことが、注釈が消えていた直接の原因でした。
4. 独自の注釈タイプを追加しようとして表示が崩れた
標準の注釈だけでなく、独自の見た目を持つ注釈を追加しようとしたところ、意図しない位置に描画されてしまう問題が発生しました。
気づいたこと:
座標系がPDFページ内座標とビュー座標で異なる
PDFKitの注釈はPDFページ内の座標系で位置を指定する必要があり、画面上のタップ位置(ビュー座標)をそのまま使うと位置がずれることが分かりました。PDFViewが提供する変換メソッドを使ってビュー座標をページ座標に変換する処理を挟むことで、意図した位置に注釈を配置できるようになりました。
まとめ
PDFViewは表示するだけならすぐ動くが、実用的な閲覧体験にはautoScalesやdisplayModeなどの調整が必要- 全ページのサムネイル生成は重い処理のため、表示範囲だけを都度生成するかバックグラウンド処理にする
- 注釈の追加はメモリ上の変更に過ぎず、
write(to:)を呼ばないとファイルに保存されない - 独自注釈の位置指定にはビュー座標とページ座標の変換が必要
見た目はシンプルなPDFビューアでも、パフォーマンスと座標系の両面で気をつけるべき点が多いと実感した実装でした。
本記事は生成AI(Claude)を活用して執筆・編集しています。内容は実体験に基づき、執筆者本人が確認・監修しています。


コメント