-

なぜ Cocoa バインディングを使うのか?

-

MVC パラダイムのサポート

-

オブジェクトモデリング

-

バインディングの使い方

-

Master-Detail インタフェースの作成

-

バインディングを使った画像の表示

- Cocoa バインディング-
バインディングを使った画像の表示

この文章は、Cocoa Bindings: Displaying Images Using Bindings を翻訳したものです。

通常、画像は NSImageCell か NSImgaeView を使って表示されます。Master インタフェースのテーブルの列に表示したり、Detail インタフェースの画像ビューに表示したりすることがあるでしょう。この 2 つのコンポーネントはにたようなバインディングを持つので、両方ともこの記事で解説します。これらのコンポーネントを使うには、画像をどのように格納して、どのようにアクセスするか、ということを決定する必要があります。また、これらのコンポーネントの value バインディングは、たくさんのフォーマットをサポートします。value バインディングに NSImage や、ファイルパス、URL などを指定することができます。

この記事で紹介する例は、「Master-Detail インタフェースの作成」の例を拡張したものです。特にこの記事では、Master インタフェースのテーブルの列に NSImageCell を(図 1 を見てください)、Detail インタフェースに NSMiageView を追加する方法を説明します。また、この記事は、独自の値変換を作り、画像のファイル名を絶対パスに変換する方法も紹介します。

Master Detail インタフェースの基本的な作り方については、「Master-Detail インタフェースの作成」を参照してください。

NSImageCell を NSTableColumn で使う

目次:

モデルの作成
ビューの作成
コントローラの作成
ビューからコントローラへのバインディング
パスを変換する値変換の使用

モデルの作成

モデルがどのように画像プロパティを定義するかは、アプリケーションによります。画像を、どのように格納してアクセスするか、によるのです。画像が、同じコンピュータ上のディスクかプロジェクトフォルダにあるならば、ファイルパス経由でアクセスできます。画像がディスク上ではなく、リモートのサーバにある場合は、URL 経由でアクセスできるでしょう。画像が同じデータソースにあるならば、画像を直接メモリに読み込むことができます。画像が読み込まれているならば、画像プロパティをただ単に NSImage オブジェクトとして定義できます。うれしいことに、Cocoa バインディングはこれらのすべてをサポートしています。

この例では、モデルは「Master-Detail インタフェースの作成」の図 2 にあるように、Media オブジェクトの imgae を表す、NSImage を使います。

ファイルパスや URL の場合は、ファイルの絶対パスや URL ではなく、ファイル名だけをモデルに格納するでしょう(たとえば、画像フォルダを動かしたときに、毎回モデルを更新するのはいやでしょう)。しかし、バインディングは絶対パスや URL が必要です。一つの解決方法は、独自の値変換を実装し、画像のファイル名を、定義に従って、絶対パスや URL に変換することです。NSImage の代わりにファイルパスを使う場合は、「パスを変換する値変換の使用」を参照してください。

ビューの作成

次に、画像ビューを作ります。NSImageView をウィンドウにドラッグするか、NSImageCell を画像を表示する列にドラッグします。

コントローラの作成

この例では、すでに Master Detail インタフェースが動作しているものとしています。もし新たに配列コントローラを作る必要があるならば、「Master-Detail インタフェースの作成」の「コントローラの作成」を参照してください。

ビューからコントローラへのバインディング

次に、画像ビューをコントローラへ結びつけます。NSImgaeView と(NSImageCell を含む)NSTableColumn には、次の value バインディングがあります。

  • value—NSImageオブジェクト
  • valuePath?画像ファイルへの絶対パス
  • valueURL?画像ファイルへのURL

注意:テーブルの列の NSImageCell を使うときは、セルではなく、テーブルの列のバインディングを設定する必要があります。NSImageCell を列にドラッグすると、NSTableColumn の Bindings ペインの Value カテゴリが変化して、追加された value バインディングを表示します(NSImageView の value バインディングと同じものを表示します)。

たとえば、図 1 のテーブルの列の value バインディングは、次のように設定します。

  1. Bind to 特性に、配列コントローラオブジェクトを設定します。たとえば、MediaAssetsController です。
  2. Controller Key 特性に、arrangedObjects を設定します(表示されているオブジェクトの集合です)。
  3. Model Key Path 特性に、その列に表示したい NSImage プロパティを設定します。たとえば、メディア管理アプリケーションでは、image へのキー・パスを設定します。

Detail インタフェースの NSImageView の value バインディングも、同様に設定します。ただし、Controller Key 特性には selection(現在選択されているオブジェクト)を設定します。

この例のバリエーションとして、valuePath バインディングを使う場合は、「パスを変換する値変換の使用」を参照してください。

パスを変換する値変換の使用

画像にアクセスするときにファイルパスを使いたいならば、ビューをコントローラに結びつける際に valuePath バインディングを使います。ですが、valuePath には、絶対パスを指定することになっています。通常、モデルには絶対パスを格納していないでしょう。ファイル名か、相対パスでしょう。次のような、独自の値変換を使うことで、ファイル名や相対ファイルパスを、絶対パスに変換することができるようになります。

独自の値変換の作成

まず、ファイル名や相対パスを絶対パスに変換する、値変換を作ります。これは、NSValueTransformer のサブクラスを作り、transformedValueClassallowsReverseTransformation クラスメソッドを上書きすることでできます。リスト 1 のようにしてください。

transformedValue: メソッドは、変換を行います。たとえば、リスト 1 に実装されている transformedValue: メソッドの実装は、プロジェクトの Resources ファイルに画像があることを前提にしています。そして、NSBundle の resourcePath: メソッドを使って、ファイル名を絶対パスに変換しています。もし画像が他の場所やファイルシステムにあるならば、この例は変更する必要があるので、注意してください。

PathTransformer の実装

#import "PathTransformer.h"

@implementation PathTransformer

+ (Class)transformedValueClass
{
    return [NSString self];
}

+ (BOOL)allowsReverseTransformation
{
    return NO;
}

- (id)transformedValue:(id)beforeObject
{
    if (beforeObject == nil) return nil;
    id resourcePath = [[NSBundle mainBundle] resourcePath];
    return [resourcePath 
            stringByAppendingPathComponent:beforeObject];
}

@end

値変換の登録

独自の値変換を使うには、最初に NSValueTransformer を登録しなくてはいけません。この場合、サブクラスではなくて、インスタンスを登録することに注意してください。通常、値変換の登録は、initialize メソッドか、アプリケーションのデリゲートの applicationDidFinishLaunching: メソッドで行います。値変換を登録するときに、論理名をつけて、バインディングを設定する際に使うことができます。たとえば、PathTransformer というインスタンスを登録するには、次のコードを applicationDidFinishLaunching: に加えてください。

id transformer = [[[PathTransformer alloc] init] autorelease];
[NSValueTransformer 
        setValueTransformer:transformer 
        forName:@"PathTransformer"];

値変換を使ったビューからコントローラへのバインディング

最後に、ビューからコントローラへ valuePath バインディングを結びつける際に、値変換を指定します。たとえば、テーブルの Image 列の valuePath バインディングを、次のように設定します。

  1. Bind to 特性に、配列コントローラを設定します。たとえば、MediaAssetsController です。
  2. Controller Key 特性に、arrangedObjects(表示されているオブジェクトの集合)を設定します。
  3. Model Key Path 特性に、画像のファイル名を含むプロパティを設定します。たとえば、メディア管理アプリケーションでは、imagePath へのキー・パスになります。
  4. Value Transformer テキストフィールドに、値変換の論理名である PathTransformer を設定します。

図 2 は、Interface Builder で NSTableColumn の Bindings ペインを表示し、valuePath バインディングを開いて独自の値変換を設定した様子です。

NSTableColumn の Bindings ペイン

代わりに valueURL バインディングを使うには、似たような値変換を実装して、ファイル名や相対パスを NSURL オブジェクトに変換します。また、PathTransformer クラスを拡張して、他のタイプのファイル名変換を扱えるようにすることもできます。後者の場合は、違うインスタンスを違う名前を使って登録して(たとえば、PathTransformerURLTransformer)、それぞれの値変換を使えるようにします。


[Home] [Download] [Archives] [BBS] [Cocoa Programming Tips 1001] [Core Foundation の秘密] [Safari Developer Center] [はじめてのブラウザのつくり方] [Sketch BP] [スクリーンセイバーを作ろう] [Objective-C 最適化] [Authorization API 完全理解] [Mac OS X Programming Books Review] [オブジェクト指向の言語比較論] [panther-dev]

mailto: mkino@xd5.so-net.ne.jp