0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【第2回】XcodeとCodexでiOS用PDFビューアを育てる――毎日のiPad試用で見つけた画質と表示の問題

0
Last updated at Posted at 2026-10-20

シリーズ:iOS版『見開きPDFビューア』開発記録

この記事は、ChatGPTと壁打ちしながら作成しました。また、Gitの変更履歴とソースコードを調査した結果を含みます。

私は本をたくさん買うのですが、電子書籍を端末に保存して読む方法には早い段階で限界を感じていました。当時は、ストレージ容量の大きい端末に買い換えても、またすぐに容量が足りなくなってしまうからです。そのため、本を読む時にダウンロードして読み終えたら端末から消去する方法か、ダウンロードしないで表示する方法で電子書籍アプリを使っています。

そこで、このPDFビューアでは、クラウドに置いたPDFを快適に開いて読めることも重視しました。Apple製品では、自分のアカウントのiCloud Driveを使う想定です。

さて、PDFの読み込み、見開き表示、検索、ズーム。基本的な機能はそろってきましたが、実際に使っていると、まだ気になるところが出てきます。開発と並行して、実機のiPadでも毎日のように試用を続けていました。

前回の記事では、GemmaとClineでiOS用のPDFビューア「MihirakiPDFViewer」を作り、2026年8月25日にChatGPTへ全面移行するまでを振り返りました。

今回は、XcodeでCodexを利用して進めた開発のうち、画質や表示、操作に関わる修正を紹介します。特に画質については、別の機能を追加したところ、通常の表示まで思いがけず改善することになりました。

他のアプリと比べて、画質がよくない

初期のバージョンをiPadで使っていて気づいたのが、PDF表示の画質です。他のアプリで表示したときと比べて、解像度が低いように見えました。

気になってはいても具体的な直し方が分からず、表示処理そのものの改善は後回しにして、別の機能を依頼しました。以下のプロンプトは入力文の全文、回答は当時の抜粋です。Xcodeが自動付加したファイル一覧などは省いています。

筆者のプロンプト(入力文全文)

PDF画像の表示時に高画質化する機能と、シャープネスする機能を追加してください。設定画面の先頭に'表示設定'グループを作り、'高画質化'と'シャープネス'の設定項目を追加してください。

Codexの回答(抜粋)

  • PageViewのPDF描画を差し替え
    • 高画質化ON時は高解像度でPDFページをラスタライズ
    • シャープネスON時はCore Imageで輝度シャープ処理を適用
  • 単ページ表示・見開き表示の両方に反映

8月29日のGit履歴にも、この追加が残っています。

すると、高画質化を有効にしたときだけでなく、通常モードの表示もきれいになりました。もともと気になっていた画質が、別の機能を追加したことで改善したわけです。これはラッキーだったと感じています。

通常モードの描画処理も変わっていた

なぜ通常モードまで改善したのか。当時、変更されたコードも確認していました。8月29日の差分を見ると、PDFから画像を作る処理が変わっています。

変更前は、次のように取得した画像を表示していました。

page.thumbnail(of: size, for: .mediaBox)

変更後は、UIGraphicsImageRendererで画像を作り、その描画先へpage.draw(with:to:)でPDFのページを描く処理になっています。この処理は、高画質モードだけでなく通常モードでも使われます。

新しい処理には、画面の倍率を考慮する計算も入っていました。

let screenScale = max(displayScale, 1)
let qualityMultiplier: CGFloat = isHighQualityRenderingEnabled ? 2 : 1
let targetScale = screenScale * qualityMultiplier

高画質化がオフでも画面倍率を使い、オンならさらに2倍を指定する構成です。ただし、描画画像の長辺には通常2048、高画質4096ピクセルの上限があるので、常に指定どおりの倍率になるわけではありません。

初期のコードでは低めの解像度で取得した画像を表示していて、新機能の追加に伴い、以前より高い解像度で描画されるようになったのではないかと思っています。

差分から確認できるのは、サムネイルを取得する処理から、画面倍率を考慮して描画する処理へ変わったことまでです。当時の画像のピクセル数や、同じ条件での比較画像は残していないため、これが画質改善の原因だったとまでは断定できません。

ともあれ、iPadで使っていて気になっていた表示は改善しました。機能を追加したつもりが、普段の表示にもよい影響があったという、少し意外な経緯でした。

検索できても、ハイライトがずれる

画質とは別に、検索結果の表示にも修正が必要でした。文字列が見つかっていても、ハイライトがその文字の上に重なるとは限りません。

前回の記事でも、検索と座標変換の調整には触れました。その後、9月29日にもiPadでのハイライト位置を直す変更が残っています。

変更前のコードでは、ハイライトの水平方向の位置を、ページが中央にあるものとして計算していました。一方、PDFの画像は、見開きの左右に応じて配置しています。画像とハイライトで、位置を決める基準が違っていたわけです。

修正では、ページの左端を求める計算をalignedPageOriginXへまとめ、画像とハイライトの両方で使うようにしています。中央配置の場合は、表示領域の幅から描画幅を引き、その半分を左側の余白にします。

(containerWidth - renderedWidth) / 2

画像は、この左端に描画幅の半分を足した位置を中心にして置きます。ハイライトにも同じ左端の位置を渡すことで、両者の基準をそろえています。

図1

図1:PDF画像とハイライトの位置の基準をそろえる修正。左は画像を右寄せし、ハイライトを中央配置の基準で計算した例、右は両方に同じ原点を使った例です。位置計算の違いを説明する模式図です。

検索の処理が正しくても、その結果を画面のどこへ描くかは別に確認が必要でした。見開きの配置を調整するときには、PDF画像だけでなく、その上に重ねる表示にも目を向ける必要があります。

メニューを出すと、本文の表示が縮小する

操作部を表示したときのレイアウトも、使い続けながら見直した部分です。8月22日の履歴を調べると、当初は筆者自身が、操作部に合わせてPDFを小さくする動作を依頼していました。

筆者のプロンプト(入力文全文)

UIを変更してください。
ファイルを開いた後は、ツールバー・検索バー・スライダーを非表示し、PDF画像を全画面で表示します。
PDF画像をタップすると、ツールバー・検索バー・スライダーを表示します。PDF画像はそれらに合わせて小さく表示します。
検索バー表示とスライダー表示の設定値は、デフォルトで有効に変更します。
ダブルタップで、ズームの拡大率をリセットします。

Codexの回答(抜粋)

  • PDFを開いた直後は、ツールバー・検索バー・スライダーを非表示
  • PDF画像を単タップすると、ツールバー・検索バー・スライダーを表示
  • 表示後はそれらの領域に合わせてPDF表示エリアが縮小

その後、読書中に本文の大きさが変わる使い勝手を見直しました。10月2日には、操作部を表示してもPDFのレイアウトを安定させる変更があります。

それまでの構成では、PDFとスライダーなどを縦に並べていました。この並べ方だと、操作部を出すことでPDFが使える高さも変わります。表示領域に合わせてPDFを拡大・縮小していれば、メニューを出す操作が、本文の大きさを変えることにもつながります。

このときの修正では、ZStackを使ってPDFの上に操作部を重ねる構成へ変更しています。本文の領域と、操作部の表示を切り離す方向の修正でした。

図2

図2:配置の違いを示す模式図です。8月22日に依頼した縮小表示(左)と、10月2日に見直した重ね合わせ(右)。左は当初の依頼に沿った動作です。右は本文の大きさを保ちますが、操作部に重なった部分は隠れます。

ただ、この構成で終わったわけでもありません。10月14日には標準ツールバーを採用する変更があり、操作部の作り方はその後も見直しています。履歴を振り返ると、その時点で気になった問題に対応しながら、画面の構成も変わっていったことが分かります。

右綴じは、左右を入れ替えるだけではなかった

このアプリで大事にしている右綴じの表示にも、修正が続いていました。10月9日の依頼では、開いた直後の位置が期待と違うことを伝えています。

筆者のプロンプト(入力文全文)

サンプルPDFを開くと、最後のページにジャンプする。Direction R2Lが反映されているか確認してください。
設定画面の実機テストと診断のボタンをオプショングループのリセットの前に移動してください。

Codexの回答(抜粋)

  • R2L PDFのページ順を逆順に配置し、最初のページから開くよう修正
  • PDFのDirection = R2L検出と見開き内のページ順が反映されていることを確認

この変更では、TabView全体へ読書方向を設定する処理を外し、右綴じの場合はページグループを逆順に並べる実装へ変えています。

見開きの中で、どちらのページを左に置くか。それと、見開き同士をどの順に並べるか。この二つは分けて考える必要がありました。見た目の左右が合っていても、開いた直後の位置やページ送りまで合っているとは限りません。

図3

図3:見開き内の左右配置と、見開き同士の読書順の違いを説明する模式図です。下段は、表紙から2・3ページ、4・5ページへ進む例です。図のページ番号は1始まりで、以下のコード説明に使う0始まりの番号とは区別しています。

10月14日には、ページの組み合わせを決める処理がPDFPageGroupingへ切り出されています。ここでは、見開きをページ番号の配列で表します。

以下は、5ページのPDFを0始まりの番号で表した例です。

条件 ページの組み合わせ
左綴じ・表紙なし [[0, 1], [2, 3], [4]]
右綴じ・表紙なし [[1, 0], [3, 2], [4]]
左綴じ・表紙あり [[0], [1, 2], [3, 4]]

右綴じでは、各見開きの中の左右を入れ替えます。表紙ありなら、先頭のページを単独にします。この配列とは別に、画面上で見開き同士を並べる順序も扱います。

こうして処理が分かれると、画面を開いて確認するだけでなく、ページの組み合わせをテストで確かめられるようになります。

使い続けながら、表示の調整も続ける

前回の記事では、見開きの隙間や配置の修正を何度も繰り返したことを書きました。ChatGPTへ移行した後も、表示の調整は続いています。

実機のiPadで使っていると、画質やハイライトの位置、操作部を出したときの見え方などが気になります。ただ、その場で気づいても、原因や直し方まで分かるとは限りませんでした。画質のように、別の機能を追加した結果、思いがけず改善したこともあります。

画質が改善したときには、変更されたコードも確認していました。通常モードの描画処理も変わっていたので、それが改善につながったのではないかと考えています。

その後のコードでは、位置の計算やページの組み合わせも、個別に確かめられる形へ整理されてきました。次の第3回では、公開できるテストPDFを用意し、表示設定の識別、検索、大容量ファイルの動作をどのように確認したかを紹介します。

ソースコードと本稿の対象

ソースコードはGitHubのtyamada/MihirakiPDFViewerで公開しています。

2026年10月20日時点では、iOS版はApp Storeの審査中で、まだ公開できていません。一方、Android版はGoogle PlayストアでVer.2.0.0を公開中です。Android版の開発についても、この後、別の記事でまとめる予定です。

本稿は2026年10月20日時点の調査に基づき、開発コードはtestingブランチの91f0853を基準にしています。Gitの変更日は開発の記録です。

前の記事:第1回:GemmaとClineでiOS用PDFビューアを作ってみた――見開き表示の修正を繰り返した約2か月
次の記事:第3回:テストPDFと識別・検索・負荷の検証

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?