ページ

2009年11月18日水曜日

BlogAssistant(2) - NSTableViewへ画像を表示する

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

(前回)Cocoaの日々: BlogAssistant(1) - CoreData を NSTableView へ表示させる(NSArrayController経由でバインド)


前回は CoreData をテーブルビューへ表示する簡単なプログラムを作った。今回はテーブルビューに画像を表示させてみよう。画像データはファイルとして保存し、CoreData ではファイル名だけを管理するようにする。


サンプル画像の準備

最初はサンプル画像を用意してそれを表示するだけにする。後々は Webページのサムネイルが表示される。
今回は  sample1.png と sample2.png と2つ用意してみた。


NSImageCell 追加

まず InterfaceBuilder を開き、テーブルビューのカラムに NSImageCell を設定する。カラムの高さは NSTableView の属性(size)で調整した。

画像の表示方法

前回同様できるだけコードを書かずにすませたい。画像の表示も Bindings を使う。ただ CoreData にはファイル名しか格納されていないのでそのままでは表示できない。なんらかの方法で NSImage に変換させる必要がある。今回は Bindings の Value Transformer という機構を使い、ファイル名 => NSImage 変換を行わせよう。


バインディング

前回の設定に Value Transformer へ ImageTransformer を追加する。これはクラス名を表していてこの後定義する。

NSValueTransformer

NSValueTransformer は bindings を使った MVCアーキテクチャの中で、モデルとビュー間のデータ形式を変換するのに使う。使い方は NSValueTransformer のサブクラスを用意し、これをビュー側の bindings設定へ追加するだけ。こうするとモデルから渡されたデータは NSValueTransformer で変換された後、ビューで表示に使われる。逆にビューから入力されたデータを NSValueTransformer で変換してモデルへ格納することもできる。


(参考)

Mac Dev Center: NSValueTransformer Class Reference
Mac Dev Center: Value Transformer Programming Guide: Introduction to Value Transformers

Cocoaの日々: アプリケーションを開くを改造する(2)
Cocoaの日々: NSValueTransformer

今回は CoreData で管理しているファイル名を元に表示用の NSImage へ変換するクラスを作ってみた。モデル=>ビュー方向の変換のみ用意してある。

ImageTransformer.h
@interface ImageTransformer : NSValueTransformer {

}

@end

ImageTransformer.m

@implementation ImageTransformer

+ (Class)transformedValueClass
{
    return [NSImage class];
}

- (id)transformedValue:(id)value
{
if (!value) {
return  nil;
}
NSImage* image = nil;
NSString* path = [[NSBundle mainBundle] pathForImageResource:value];
if (path) {
image = [[NSImage alloc] initWithContentsOfFile:path];
}
return image;
}
@end


今回はサンプル画像がリソースフォルダ内にあるので、CoreDataから取り出したファイル名(value)を元に NSImage インスタンスを生成して返す。


動作確認

さて動かしてみよう。


おー出た。

こうも意図通りに動くと楽しくてしょうがない。
徐々にバインディングとCoreDataのコツが掴めてきた気がする。
Cocoa プログラミングは面白い。


ソースコード

BlogAssistant at master from xcatsan's SampleCode - GitHub

※git に慣れてなくて機能のコードを上書きしてしまった。。タグ使い方を勉強をせねば。