Tips

Objective-CでPDFViewerを作成する 第1回

4.描画用のクラスを作成

次に描画用のクラスの方を見ていきましょう。
次にPDFを表示させるためのViewをUIViewを継承して作成することにします。

   UIViewを継承したサブクラスを作成

Xcode右側ペインからコンテキストメニューの「New File」をクリックします。
新しいファイルのテンプレートを選択する画面で「Objective-C Class」を選択し次に進みます。
今回「PDFView」としています。先ほど述べたように継承元は「UIView」としています。
pdf-o-1-5

保存場所を指定して「Create」で終了です。
pdf-o-1-7

Xcode右側ペインに追加されているのが確認できると思います。
次にコードを追加していきます。

   ヘッダーファイルにプロパティ追加

まずPDFView.hから追加していきます。こちらはCGPDFPageRefを保持するためのプロパティを用意します。
PDFView.hファイル

@interface PDFView : UIView

@property(nonatomic) CGPDFPageRef pdfPage;

@end

   クラスに処理を追加

次に実際の処理を「PDFView.m」ファイルに実装していきます。セッタ、ゲッタを自動生成するために
synthesizeディレクティブを使用します。
描画処理は「drawRect」メソッドの部分に記述していきます。

@implementation PDFView

@synthesize pdfPage = _pdfPage;

~~一部省略~~
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
    // Drawing code
    if(!_pdfPage){
        return;
    }
    CGContextRef context;
    context = UIGraphicsGetCurrentContext();
    CGContextDrawPDFPage(context, _pdfPage);

}
@end

セッタ、ゲッタを自動生成するためにsynthesizeディレクティブを使用しています。
書式はプロパティ名 = インスタンス変数名となります。

15行目で描画関連のデータを管理するコンテキストをUIGraphicsGetCurrentContext関数を使用して取得しています。
描画関連の処理はこのコンテキスト利用して行っていきます。
16行目で取得したPDFページを描画しています。

コードの実行

では実行してみましょう。おかしな画像になっていると思います。
上側が元のPDF、下側がiOSシミュレータ上の表示です。画像が上下反転しているのが確認できると
思います。
pdf-o-1-10
pdf-o-1-9

座標系の調整

Core Graphicsのフレームワークでは左下が原点となるのですが、UIKitでは左上が原点となって
しまいます。そのために画像が上下反転します。
そこで画像の拡大や回転といった処理の際に使われるアフィン変換を使用して調整します。
現在の座標系をY軸に-1倍拡大すればまず上下反転します。しかし原点が左上のままだと画面外の方に拡大されているため
表示画面内から消えてしまいます。
そこでPDFのサイズ分、原点を移動させます。座標系を上下反転させているため上が正の方向となります。
よって原点をマイナス画面サイズ分動かすことになります。
pdf-o-1-8
また先ほどの表示結果では1画面に収まりきっていないため、収まるように調整もします。
そのためにCGPDFPageRefから縦横のサイズを取得して、画面の領域との比率をだしその分拡大縮小を行います。
以下のように「drawRect」メソッドの部分を変更します。

- (void)drawRect:(CGRect)rect
{
    // Drawing code
    if(!_pdfPage){
        return;
    }
    CGContextRef context;
    context = UIGraphicsGetCurrentContext();
    //上下反転を修正する 原点を左下に移しY軸を反転させる
    CGContextScaleCTM(context, 1.0f, -1.0f);
    CGContextTranslateCTM(context, 0, -CGRectGetHeight(rect));

    //PDFページのサイズを取得
    CGRect pdfRect = CGPDFPageGetBoxRect(_pdfPage, kCGPDFArtBox);
    CGContextScaleCTM(context,rect.size.width/pdfRect.size.width,rect.size.height/pdfRect.size.height);

    CGContextDrawPDFPage(context, _pdfPage);

}

10行目のCGContextScaleCTM関数で座標系をY軸に-1倍しています。第2引数がX軸方向の倍率、第3引数がY軸方向の倍率
となります。
11行目のCGContextTranslateCTM関数で原点を平行移動させています。
CGRectGetHeight関数を使用して表示領域の縦幅を取得しその分マイナス方向に移動させています。
14行目ではCGPDFPageGetBoxRect関数を使用してページサイズを取得しています。
pdf-o-1-11
これで一画面に収まるようになりました。
しかしページ送りの機能も拡大縮小の機能もありません。
次回以降こういった機能を足していきます。

TechProjin 開発系基礎講座 連載リンク

基礎からPHPWEBアプリ解発を学ぶなら・・
PHP基礎 連載

AIなどで注目急上昇!これから学ぶならPython!!
独学で学ぶ-pythonプログラミング 連載

汎用性◎ 定番プログラミング言語JAVA
Java基礎講座 連載

Recent News

Recent Tips

Tag Search