プロジェクト名の変更2009/04/13 18:04

Property
これがけっこう面倒です、と言うより普通の操作だけでは不可能でした。

最初はCodeWarrior版と同じ名前でプロジェクトを作成しておりましたが、中味がかなりできていたので新規に作り直すのは面倒な状況でした。
そこで名称変更をおこなったのですが、変更しても何故か?コンパイルなどをすると元に戻ってしまいました。
また、[プロジェクト名の変更:ProductsのLPrint.app]を変更できないのです。
メニュー/プロジェクト/アクティブな実行可能ファイルLPrint.appを編集/ で表示はされるが変更ができない。

変更方法:
(Application/Utilities/Property List Editor)を使ってproject.xcodeproj内のファイルを編集する。
 つまり、LPrintをAnythingPringに手作業で修正する。
その後フォルダbuild内にある旧ファイルを削除と名称変更すれば完了である。

Viewに行番号の表示方法は?2009/04/12 10:35

LineNumber
AnythingPrintにはテキスト文書は行番号を付けて表示させる仕様があります。
どうやらNSRulerViewを使えば実現できそうなことが分かりましたが、詳しい説明をおこなっている文書が見つかりません。
図左下は単純にルーラを表示させたものですが、このまま印刷するとルーラ部分は印刷されません。
など、現在調査中ですが、判明したところまでを記述しますと。

まず、NSRulerViewのサブクラスを作成します。
@interface LineNumberView : NSRulerView
{
}
インスタンスを作成します。
LineNumberView *lineNumberView;
lineNumberView = [[LineNumberView alloc] initWithScrollView:scrollView];

サブクラス LineNumberView内に計算や表示などのメソッドを作成してメインから呼び出す。
取りあえずscrollViewはInterfaceBuilderで作成したものを使う、つまり図左下のNSTextViewです。

これだけの話なのですが、FontやColorなど色々な要素がありなかなか面倒で理解しきれておりません。
出来上っても複雑で説明できない可能性もありますが、今回は状況説明までで終了します。

話が少し横にずれますが、NSTextViewは巨大なクラスのようです。
これだけで、ひとつのアプリケーションと言えるほどのメソッド数が存在しております。
それでほとんどのエディタがNSTextViewを使っている理由のようです。

図右は何もしなくてもスタイルなどを簡単に表示できますし、
マウスで文字を選択してスタイル変更も動作します。

NSTableViewのスクロールバーが表示されない2009/04/11 10:32

awakeFromNib
初期ダミーデータをNSTableViewの表示行数以上作成してもスクロールバーが表示されない。
データは作成されているのですがスクロールバーが表示されないのです。

この状態でマウスでタイトルをスライドしてやると表示された状態になる。

【原因(理由):】
初期化メソッドは、-(id)initと-(void)awakeFromNibの2つ存在しております。
実行される順番は、init: 次にawakeFromNib:です。

init:でダミーデータ作成すると問題ないですが、
awakeFromNib:でダミーデータ作成するとスクロールバーが表示されない不具合が起きました。

どうやら自分のawakeFromNib:を実行した時点ではViewのロード処理が終了しているようです。

NSTableViewに値を設定できない2009/04/10 10:27

NSTableView
図のDummyXが表示されているのがNSTableViewで、番号と名前を表示させております。
ここは表示しているだけですが、内部的にはNSArrayなどで保持した情報が存在します。
例えば、ファイル名、パス情報、ファイル識別情報などになります。
ここまでは単なるロジックですので問題はありません。

NSTableViewへの表示処理は下記のデリゲートメソッドがおこないます。
- (int)numberOfRowsInTableView:(NSTableView *)aTableView;
- (id)tableView:(NSTableView *)aTableView
    objectValueForTableColumn:(NSTableColumn *)aTableColumn
    row:(int)rowIndex;
このメッソドで表示数と表示データを返してやればNSTableViewに反映されるわけです。

ところがこのデリゲートメソッドで値を返しているにもかかわらず表示に反映されないのです?
表示どころかフリーズしたようにも感じられます。
間違いなく呼び出しはされています。

/************************************************************/
じつは下記のようにダミーデータを作成していました。
int i;
fname = [[NSMutableArray alloc] init];
for (i=0; i<20; i++) {
  [fname addObject:[NSString stringWithFormat:@"Dummy%d",i]];
}

デリゲートメソッドtableViewは次のとおりですが、これは問題なしです。
- (id)tableView:(NSTableView *)aTableView
    objectValueForTableColumn:(NSTableColumn *)aTableColumn
    row:(int)rowIndex
{
  id identifier;
  identifier = [aTableColumn identifier];

  if([identifier isEqualToString:@"no"]){
    return [NSNumber numberWithInt:rowIndex];
  }
  else if([identifier isEqualToString:@"name"]){
    return [fname objectAtIndex: rowIndex];
  }
  else{
    return nil;
  }
}
ロジックとしてはおかしいところはありませんが、'Dummy00'が表示されませんでした。

【理由:】
メソッドの戻り値として返ってくるオブジェクトは、そのままではどこか知らない場所からの解除によって解放されている危険性が常にある。
よって、その危険を避ける必要がある場合、明示的に保持(retain)しなければならない。
もちろん保持した場合は、必要がなくなった時点で責任を持って解除(release)する必要がある。

for (i=0; i<20; i++) {
  [fname addObject:[NSString stringWithFormat:@"Dummy%d",i]];
}
[fname retain];  //← これがキモ!
[myTableview sizeToFit];  //再表示させる

このバージョンのCocoaのメモリ管理はかなり厄介な問題を持っているようです。

changeFontメソッドが呼ばれない2009/04/09 09:08

フォントパネル
フォントはフォントパネルを表示させてデリゲートメソッドを用意すれば取り出せます。
デリゲートメソッドとはフレームワークCocoaが必要があると自動的に呼び出すメソッドを言います。

AnythingPrintではタブ切替えをおこなっていますが、この切替えをおこなうと何故か呼ばれなくなります。
勿論、パネルを表示させた直後は問題なく呼びだされていますが、レスポンダーリンクから外されてしまうようです。

クラス構造を考えたり、レスポンダーのメソッド呼び出しを追加したり、色々やりましたが解決しません。
ネットを探し回ってやっと英語サイトでこの方法が使えることを見つけました。
これはいくら考えても分らない・解決できない問題です。

解決方法は、
フォントパネルを表示させるときに下記メソッドを追加する。
[fontPanel setBecomesKeyOnlyIfNeeded:NO]; //changeFontチェイン継続
[fontPanel setDelegate:self];

【メソッド解説】では、
 「必要な時だけキーウインドウになるかを返します。」
 「初期設定はNOを返します。 」
と記載されておりますが、これだけで使える人はいないのでわ?

日本語表示のメニュー2009/04/08 09:04

日本語メニュー
Xcodeが最初に作成するのは英語のMainMenu.nib(English)ファイルです。
日本語化する手順が必要です、
MainMenu.nib(English)を選択してから、ファイル-情報をみる
言語を追加...でJapaneseを選択して追加ボタンを押す。

しかし、日本語化版を作成してもInterfaceBuilderでの表示は英文のままです。
これを手作業でひとつひとつMainMenu変更などしたら大変すぎるでしょう。

これは裏技なのか、正規手順なのか不明ですが?

InterfaceBuilderだと自動作成される。それにコピペしたほがが良い。
(メニューの File/New/ でLanguageをJapaneseにしてNewボタンを押す)

でも、部品パレットからFontメニューを追加すると英文になってしまうのですよね!

Xcodeで漢字を使えない?2009/04/07 14:39

Xcodeを立上げて新規プロジェクトを選択して...などと基本手順を書いてもつまらないのでやめます。
動き出すと気にもしないようなもので、はまった事柄について紹介しようと思います。

プロジェクトを作成してソースファイルに漢字を入力すると保存できませんでした。
しかたがないのでMacOS-X標準のテキストエディタで作業しておりました。

何の事はない、Xcodeの最初の設定が問題だったのでした。
環境設定/テキスト編集/デフォルトのファイルエンコーディングにUnicode(UTF-8)を選択しておけば問題解決です。
これで新規作成したものは問題なく漢字が使えます、でも既に作成したファイルはだめなので削除して作りなおします。

インスタンスと接続する2009/04/06 16:51

Outlets&Action
ウィンドウ上のボタンなどをインスタンスと接続してはじめて動作を制御可能になります。
画面インスタンスはInterfaceBuilderで作成して、AppController.mに制御ロジックを記述します。
Target/Actionとは、ボタンが押されたときに実行するメソッドです。
Outletsとは、メソッドが画面ビューにアクセスするためのオブジェクトのポインタです。

画像はインスタンスAppControllerのものです。
ひとつしか作成しないと全部ここに記載することになるので具合が悪そうです。
機能ごとにインスタンスを作成するのが正常な設計でしょう。

開発環境 InterfaceBuilder2.52009/04/05 16:54

ひとつのウィンドウに部品を配置したアプリを作成します。

AppControllerとModelControllerはどちらもNSObjectのサブクラスなので同じものですが、
『File's Owner → AppController』『AppController → ModelController』とデリゲート接続されています。

これはMVCを実現しようと考えてAppControllerはModelControllerを通してモデルにアクセスさせようと考えたものです。
例えば「AppController」でボタンのクリックを受け取り、処理は「ModelController」を呼び出すことにしました。
しかし、必要がないことが分りましたが、これはこれでも良いかなと言うところです。
「AppController」と「ModelController」のどちらでも「OutletとAction」を直接に接続できます。
もっと複雑なアプリの場合には、このModelControllerを沢山作成してゆけば機能分割できると言うことでした。

いずれにしても「AppController」とは別にInterfaceBuilderのインスタンスを作成しないとロジックを全部「AppController」に記述することに成りかねません。

「Font Manager」が薄い水色で作成されておりますが、普通には作成できないインスタンスでした。
これは部品パレットからFontメニューをドラッグ&コピーすると自動的に作成されます。

開発環境 Xcode2.52009/04/04 14:29

今回は単独ウィンドウのツールアプリなのでCocoaApplicationです。
立上げ当初は調査と実験が必要なのでもっと多くのクラスファイルを作成しておりましたが、現在はご覧の通りシンプルです。

AppController:アプリケーションのコントロールクラスです。
ModelController:モデルクラスの制御用に設けたコントロールクラスです。
FileSystemItem:モデルクラスのモジュールです。

InterfaceBuilderのインスタンスとして作成したのは「AppController」と「ModelController」の2つです。
「FileSystemItem」は既存サンプルをそのまま持ってきてAnythingPrint仕様に合わせた修正を加えてあります。
これは階層ツリーでファイル情報を取得するのに使っています。

InterfaceBuilderの画面と合わせて見ないと分りにくいですが、アメブロは1記事1画像の制約があるのでしかたがありません。

それからアプリ名は「AnythingPrint」にしました、理由は文書だけでなく画像も印刷することにしたからです。
さらにバイナリデータも印刷可能とする為に16進数に変換しての印刷もおこなえます。
つまり、何でも印刷(Anything)です。