Cocoaでいこう! Macらしく 第30回
Yoshiki(DreamField)
この記事は、MOSAが発行するデベロッパ向けのデジタルマガジンMOSADeN 第92号(2003年12月2日発行)に掲載された記事です。2〜3ヶ月遅れで、ここに掲載して行きます。

画像のスクロールを実現しよう

前回はNSViewを継承したクラスを作り、これに画像の表示を実装しました。これにより、画像は表示できるようになりましたが、ウィンドウのサイズを縮めると、はみ出た部分は見えなくなります。今回はスクロールバーを追加し、はみ出た部分もスクロールさせて見れるようにします。

それでは、いつもの様にTinyView.pbproj(もしくはTinyView.xcode)を開いて下さい。そして、MyDocument.nibをダブルクリックしてInterface Builderで開いて下さい。開いたら、デザインウィンドウでMyImageViewクラスのインスタンスを選択して下さい(fig.01)。

[fig.01] デザインウィンドウでMyImageViewを選択する

そして、「Layout」メニューから「Make subviews of」を選び、表示されたサブメニューから「Scroll View」を選んで下さい(fig.02)。

[fig.02] 「Make subviews of」のサブメニューから「Scroll View」を選ぶ

するとNSScrollViewクラスのインスタンスが生成され、MyImageViewクラスのインスタンスはそれのSub viewになります。つまり、中に取り込まれるわけですね。見た目はMyImageViewクラスのインスタンスにスクロールバーが付いたように見えます(fig.03)。

[fig.03] MyImageViewにスクロールバーが付く

この両者の関係は、nibファイルウィンドウをOutline modeにすることにより、確かめることができます(fig.04)。

[fig.04] MyImageViewはNSScrollViewのSub viewになっている

スクロールバーは付きましたが、ウィンドウの端との間に隙間があります。NSScrollViewクラスのインスタンスの端の点をドラッグしてウィンドウのサイズ一杯に広げてください(fig.05)。

[fig.05] NSScrollViewをウィンドウ一杯まで広げる

これで隙間は無くなりました。ですが、このままではウィンドウをリサイズした時にそれについてきてくれません。この指定を行うために、NSScrollViewクラスのインスタンスのinfoウィンドウを開いてください。開いたらポップアップメニューでSizeに切り替え、Autosizingの指定を行って下さい(fig.06)。

[fig.06] NSScrollViewのAutosizingの指定を行う

この辺りの詳しい説明は第3回で既に行っていますので、忘れた方はそちらを参照してください。

それではビルドして実行してみましょう。適当な画像ファイルを開いてみて下さい。そしてウィンドウのサイズを画像よりも縮めてみましょう。スクロールバーを操作することにより、ウィンドウのサイズを越えた部分も、見ることが出来るようになったと思います(fig.07)。

[fig.07] スクロールバー付きの表示を実現
(サンプル画像は、ゆきみだいふくさんのご好意により、使用させていただいています。)

ところで、開いた画像はMyImageViewクラスのインスタンスよりも大きいサイズでしょうか。大きいサイズを開いた方は気付かれたと思いますが、今のままでは、はみ出た部分は切れてしまい、表示されません(fig.08)。

[fig.08] 右側が本来の画像。はみ出た部分は切れている。
(サンプル画像は、ゆきみだいふくさんのご好意により、使用させていただいています。)

これは、MyImageViewクラスのインスタンスのサイズを、表示する画像に合わせて調節していないからです。この対処をプログラムで実装します。MyImageView.mを開いてください。現在のsetImage:は、次の様になっているはずです。

- (void)setImage:(NSImage *)newImage{
    image = newImage;
    [ image retain];
}

ここに処理を加えて、imageをセットする時、そのサイズに合わせて自分自身のサイズも調節することにします。次の様に4行目を加えて下さい。

- (void)setImage:(NSImage *)newImage{
    image = newImage;
    [ image retain];
    [ self setFrameSize:[ image size]];
}

imageのサイズを取得し、自分自身のフレームのサイズにセットしています。これでMyImageViewクラスのインスタンスは、imageと同じサイズになるはずです。それではビルドして実行してみましょう。今度は端まで表示できるようになったと思います(fig.09)。

[fig.09] スクロールさせると、画像の端まで表示されるのが分かる
(サンプル画像は、ゆきみだいふくさんのご好意により、使用させていただいています。)

これでスクロールを使って画像を端まで全部表示できるようにするという目的は達しました。ですが通常のMacのアプリに比べると、大分見劣りがします。画像を開いた時、ウィンドウのサイズはいつでもInterface Builderで設定したサイズで開いてしまいますし、zoomボタンを押しても、ウィンドウは画像のサイズを無視して画面一杯に広がってしまいます(fig.10)。

[fig.10] Resizeボタンを押すと、画面一杯に広がってしまう
(サンプル画像は、ゆきみだいふくさんのご好意により、使用させていただいています。)

Macのアプリでしたら、当然画像のサイズに合わせて、自動調節されるべきでしょう。次回は、この辺りに手を入れて行きます。

前頁目次次頁