//yan's Diary: Cocoa yan's Diary: Cocoa
ラベル Cocoa の投稿を表示しています。 すべての投稿を表示
ラベル Cocoa の投稿を表示しています。 すべての投稿を表示

2011/06/30

「iOSプログラミング入門」を買ってしまった

給料もでたので、iPhone等のプログラミング専門書を衝動買いしてしまいました。まだ精読できていませんので、内容についてのコメントはできません。検索エンジン等でこのブログにたどり着いた方、申し訳ありません。

iPhoneなどの携帯デバイスや、Macのプログラミング開発環境である"Xcode"がバージョンアップしたつうのはGWの5/5にアップさせてもらいましたが,イマイチ取っつきにくかったので、参考書を探したりしていました。

今回紹介する本がベストかベターか、私好みかどうかはまだわかりません。ただ著者の大津真氏の本は過去にMacとUNIX関連の書籍を数冊読ませていただき、個人的に判りやすく好きであります。そんなんで、今回も期待するところです。

でも、やっぱiPhoneのプログラミング→アプリ開発は、有償なのが素人の参入の敷居を高くしていますね。Apple社の審査はいいとして、無料アプリに限るとか、自身のiPhoneでの動作確認に限るとかで、無償にできないものでしょうかね。それで上手くいきそうだったら、ロイヤルティを支払うのも気にならなくなると思うんですけど・・・。
 
 

2011/01/09

新Macのプログラミング入門 その8

半年振りの「新Macのプログラミング入門」です。正月明けの三連休で、風邪が治りきらず外に出る気にならないため、久しぶりにやってみます。

やはり教科書は”ヒンギス本”です。17章P256のチャレンジ問題に挑戦しましょう。教科書通りにプログラムすると下の図のような結果が得られます。

教科書どおり

チャレンジ問題では「この(ランダムな)直線を曲線に置き換えてください。」というものなので、こんなふうにしてみました。

曲線に換えてみた

以下に.mファイルを示します。線を描く部分の抜粋です。
”//”でコメントアウトしてある部分は、教科書通りにランダムな直線を描くループになっていまして、その下のループの部分が曲線を描く様に変更(追加)したところです。

- (id)initWithFrame:(NSRect)rect {
if (![super initWithFrame:rect]) {
return nil;
}
srandom(time(NULL));

path = [[NSBezierPath alloc] init];
[path setLineWidth:3.0];
NSPoint p = [self randomPoint];
[path moveToPoint:p];
int i;  
//for (i = 0 ; i <15 ; i++) {   ・・・教科書どおりの直線を描くループ
//p =[self randomPoint];    
//[path lineToPoint:p];     
//}             ・・・ループ終了         


for (i = 0; i <15 ; i++) {   ・・・チャレンジ問題の曲線を作るループ
NSPoint q = [self randomPoint];     
NSPoint r = [self randomPoint];     
NSPoint s = [self randomPoint];     
[path curveToPoint:q controlPoint1:r controlPoint2:s]; ・・・曲線を書くメソッド
}
・・・ループ終了     
[path closePath];
return self;
}
}

ベジェ曲線を描く”curveToPoint: contorolPoint1: conrolPoint2:”というメソッドが見つかれば、後は試行錯誤でなんとかなりますので、そんなに難しくなかったですかね。
 
 

2010/05/05

新Macのプログラミング入門 その7

Mac、およびCocoaファンの皆様、なんとGWスペシャルということで2回連続して「新Macのプログラミング入門」をアップします。さすがにGWは趣味の時間がたくさんあって、ええなぁ。


今回は前回の続きみたいなもんですが、「ヒレガス本第3版」P223第14章のチャレンジ問題に挑戦します。

本書P223には、「NSApplicationは、NSApplicationDidResignActiveNotificationという通知をポストします。」とあります。同じページの14.8にはこのような通知を受けた場合のメソッド名の決まりが載ってます。すなわち、メソッドは次のようになると思われます。また、オブザーバは自動で登録されるとのことで、実装する必要はないと思われます。

-(void)applicationResignActiveNotification(NSNotification *)aNotification {
beep();
}


ところが、このメソッドを”AppController.m”ファイルに実装して、”File's Owner”から”AppController”へのデリゲート接続を確認しても、うんともすんとも言わず上手く動作しません。そんな訳で、デベロッパドキュメントで、”NSApplicationDidResignActiveNotification”を調べてみると、似たような通知に”NSApplicationDidBecomeActiveNotification”つうのがみつかりました。私のつたない英語力でもresign=辞める、become=成る、となると”〜become〜”の方がチャレンジ問題、「アプリケーションがアクティブになった際、ビープ音を鳴らすようにしてください」には適していると思われます。


ということで、以下のメソッドを”AppController.m”ファイルに実装してみたところ、上手く動作するようになりました。

- (void)applicationDidBecomeActive:(NSNotification *)nc {
NSBeep();
}

尚、ビープ音はシステム環境設定で設定したものなので、このままではこのアプリからは変更できません。

それにしても「NSApplicationは、NSApplicationDidResignActiveNotificationという通知をポストします。」の部分は誤植なのか、本当に読者を試しているのかよく判らないですね。「その2」でも本書の記載が怪しいのか、ひっかけなのかわからないという事件に遭遇しましたが、今回も真相は著者と訳者にしかわからないんでしょう。ちなみに、私は原著を確認するほどの強者ではありませんので、あしからず。
 
 

新Macのプログラミング入門 その6

今回の「新Macのプログラミング入門」も、例によって「ヒレガス本第3版」を素材に使っています。今回のコードはかなり無理矢理な感じで、自信ありません。わかっている人ならもっとシンプルに書けそうな気がしますが、とりあえず恥を忍んでアップしてみます。例によってMacのプログラミングにまったく興味の無い方、休日に詰め将棋や詰め碁を楽しんでいる”波平さん”みたいなものなので、そんな風にごらんください。

前回「その5」で紹介、および私なりに解説したのが、P216の第13章のチャレンジ問題。本書を次の第14章へと読み進めていくと、やっぱり”このままじゃいかんなぁ”という気になってきます。本書P217にもあるとおり、”Preference=環境設定”パネルの設定は既にオープンされているウィンドウには働かず、設定以降新たにオープンされるウィンドウにしか適用されません。チャレンジ問題で環境設定を初期値に戻すリセットボタンを設置した訳ですが、このリセットボタンも同様に、リセット後新たに開いたウィンドウは初期値に戻されてても、既にオープンしているウィンドウはリセットされずそのままの状態です。実際にこういう動作をするアプリって結構見かけますが、どうでしょう。そんでもって、これはまさしく第14章の”通知=Notificationの使用”が解決する内容ですので、私なりに修正してみました。

先ずリセットボタンが押されたという通知に名前を付けるため、”PrefernceController.h”ファイル内で、以下の赤文字のグローバル変数を新規に宣言します。宣言する場所は、”@interface”の直前にしています。変数なので、名前の付け方は適当ですよ。

extern NSString * const BNRTableBgColorKey;
extern NSString * const BNREmptyDocKey;
extern NSString * const BNRColorChangedNotification;
extern NSString * const BNRColorResetNotification;



続いて"PreferenceController.m"ファイルで、以下のとおりグローバル変数(赤字)を実装します。これまた実装する場所は、”@implementation PreferenceController”の直前にしました。

NSString * const BNRTableBgColorKey = @"Table Background Color";
NSString * const BNREmptyDocKey = @"Empty Document Flag";
NSString * const BNRColorChangedNotification = @"BNRColorChanged";
NSString * const BNRColorResetNotification = @"BNRColorReset";



次に、”PreferenceController.m”の”-(IBAction)resetPreference:(id)sender”メソッドに、以下のように赤字の部分を追記します。このアクションメソッドは環境設定パネルのリセットボタンの動作内容を決めます。追加した部分は、リセットボタンが押されたことを既にオープンしている複数のウィンドウにポスト(公表)するものです。ここでバックグラウンドカラーの初期値を得るのため、あの変数この変数と試してみたのですが上手くいかず、結局一度リセットさせた”colorWell”から初期値を得ることにしました。どうも腑に落ちない部分です。

- (IBAction)resetPreference:(id)sender {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults removeObjectForKey:BNRTableBgColorKey];
[defaults removeObjectForKey:BNREmptyDocKey];
[colorWell setColor:[self tableBgColor]];
[checkbox setState:[self emptyDoc]];

NSColor *color = [colorWell color];
NSData *colorAsData = [NSKeyedArchiver archivedDataWithRootObject:color];
[[NSUserDefaults standardUserDefaults] setObject:colorAsData forKey:@"defaultColor"];
NSDictionary *defaultValues = [NSDictionary dictionaryWithObject:color forKey:@"defaultColor"];
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc postNotificationName:BNRColorResetNotification object:self userInfo:defaultValues];
}



さらに、リセットボタンが押されたという通知のポストを監視するオブザーバを、各ウィンドウの動作内容を定めている”MyDocumnt.m”ファイル内の”- (id)init”メソッドに追加しました。”BNRColorResetNotification”という名前の通知がポストされたら、”@selector()”で指示された”resetColorChange:”メソッドが呼び出されるしくみです。

NSNotificationCenter *nc2 = [NSNotificationCenter defaultCenter];
[nc2 addObserver:self
selector:@selector(resetColorChange:) name:BNRColorResetNotification object:nil];



最後に”MyDocument.m”ファイル内に、”resetColorChange:”メソッドを実装すればOKです。

- (void)resetColorChange:(NSNotification *)note {
NSColor *color = [[note userInfo] objectForKey:@"defaultColor"];
[tableView setBackgroundColor:color];
NSLog(@"reset color is %d",color);
}


なんとか第13章のチャレンジ問題を、私なりに修正した次第です。まっ、こういう時間と労力のかかる趣味も、GWならではとういうことでご勘弁ください。
 
 

2010/04/11

新Macのプログラミング入門 その5

今回の題材も「ヒレガス本」第3版です。P216第13章ユーザーデフォルトのチャレンジ問題に挑戦してみます。

”Preference.h”ファイルに以下の赤文字のアウトレット"resetPreference"と、アクションメソッド'resetPreference:"を追加して保存します。この"resetPreference"は、"Preferannce=環境設定"パネルに設置することで、ユーザーが変更した環境設定を、アプリ起動時の初期値に戻すリセットボタンになります。また"resetPreference:"はこのリセットボタンが押された時に呼び出され、初期値に戻すメソッドになります。

@interface PreferenceController : NSWindowController {

IBOutlet NSColorWell *colorWell;
IBOutlet NSButton *checkbox;
IBOutlet NSButton *resetPreference;

}

- (IBAction)changeBackgroundColor:(id)sender;
- (IBAction)changeNewEmptyDoc:(id)sender;
- (NSColor *)tableBgColor;
- (BOOL)emptyDoc;
- (IBAction)resetPreference:(id)sender;

@end



ヘッダファイルの編集が終わると、実際にパネルにリセットボタンを設定します。
”Interface Builder”で"Preference.xib"ファイルを起動して、左図の感じでリセットボタンを新たに設定します。その後”File's Owner”とリセットボタン間で、お互いターゲットとしてボタンを、アクションメソッドとして"resetPreference:"を接続します。



次に"Preference.m"ファイルにアクションメソッド'resetPreference:"を実装します。P209に、アプリ起動後にユーザーが変更した環境設定は、"removeObjectForKey:"メソッドで初期値に戻す事ができると記載してありますので、そのまま使ってみます。

最後の赤文字の2行は、ユーザーに設定値が元に戻った事を伝えるために、環境設定パネルのカラーウェルの表示色と、チェックボックスのチェック状態をアプリ起動時の初期値に戻しています。ユーザーフレンドリーのため「環境設定ウィンドウを更新し、新しいデフォルトが反映されるように」するためのコーディング(処置)です。

- (IBAction)resetPreference:(id)sender {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults removeObjectForKey:BNRTableBgColorKey];
[defaults removeObjectForKey:BNREmptyDocKey];
[colorWell setColor:[self tableBgColor]];
[checkbox setState:[self emptyDoc]];
}

今回のチャレンジ問題はボタンとメソッドをひとつづつ設定するだけやったし、ヒントが比較的判りやすく記載されていたので、簡単でしたね。

例によってMacを使っていない方、Macのプログラミングにまったく興味の無い方、「ヒレガス本」を持っていない方にはなんのこっちゃ全然わからないでしょうが、ご勘弁を。
 
 

2010/03/21

新Macのプログラミング入門 その4

「新Macのプログラミング入門」シリーズは、「ヒレガス本第3版」のチャレンジ問題を中心に扱っております。そんな訳で今回は第8章、P141のチャレンジ1を題材にします。「ヒレガス本」を持っていなければまったく面白くないですが、その辺はご容赦を。

今回のチャレンジ問題は、テーブルのソート(並び替え)を入力した文字数の大小でやりなさいというものです。結果、ソート対象のテーブルを選択して、”InterfaceBuilder”で”Sort Key”を図の赤い囲みのようにピリオドを使ったキーパス形式に代えるだけでOK。判ってしまえばどうってことないのですが、これでも試行錯誤の末にたどり着いたのですよ。キーパスに関しては、第7章P125を参考にしましょう。

この第8章は、大雑把に言えば”NSArrayController”を使うと、”TableView”のデータ挿入や削除、修正等が簡単に実装できるようになりますよという内容です。P141のチャレンジ2の問題では、”NSArrayController”とバインドを使わないでやってみましょうというものですが、これに関しては、2/6アップの「その1」で、今回とよく似たテーブルの表示を扱っています。こっちは第6章のデーターソースを用いた実装を参考にしています。
実際にやってみると、”NSArrayController”とバインドを使ったこちら(第8章)の実装方法が、コードを書く手間が少なくて簡単だと思いますが、iPhone用アプリでも使えるのかいな。
 
 

2010/03/14

新Macのプログラミング入門 その3


今回の題材も「ヒレガス本」からです。第12章、P204のチャレンジ問題から派生させ、オリジナルな”Aboutパネル”の作成をやってみました。

チャレンジ問題自体は第12章の”Preferenceパネル”を作る方法をトレースすることで解けるのですが、出来上がったのっぺらぼうの”Aboutパネル”を肉付けして、見栄えをよくする方法でつまずいてしまいます。
元々標準で用意されている”Aboutパネル”を解析してみたところ、”orderFrontStandardAboutPanel:”というメソッドが使用されています。そこでこれから標準パネルの構造を調べて流用する方法を試みたのですが、よく判らず終い。結局、標準で用意されている”Aboutパネル”そのものをカスタマイズする方法を調査してみました。


以下のメソッドを”AppController.h”で宣言して、”AppController.m”で実装します。ポイントとなるのは、”orderFrontStandardAboutPanelWithOptions"というメソッドです。

”InterfaceBuilder でメインメニューの”About NewApplication”と”AppController”オブジェクトを接続して以下の”showAboutPanel:”メソッドを選択、接続します。

メソッドの内容ですが、VOXYの写真は”images-1”というファイル名で予め”resources”に保存しておきます。今回はpng形式を使いましたが、jpgやgif形式なんかでもいいんでないでしょうか。でも普通はアイコンのイメージを使うんでしょうね。イメージ以外の部分については、変数optionsのキーとの関係と、上記パネル写真での文字の表示位置をみて、なにがどうなっているか確認してください。

また、”Aboutパネル”の下半分のスクロールする部分の記述については、今回はやっていませんが、予め用意されている”cridits.rtf”ファイルを編集すると内容の書き換えが可能です。

- (IBAction)showAboutPanel:(id)sender {
NSDictionary *options;
NSImage *img;

img = [NSImage imageNamed: @"images-1"];
options = [NSDictionary dictionaryWithObjectsAndKeys:
@"1.0", @"Version",
@"Super App", @"ApplicationName",
img, @"ApplicationIcon",
@"Copyright 2009-2010, YanSoftware", @"Copyright",
@"Super App v1.0", @"ApplicationVersion",
nil];

[[NSApplication sharedApplication] orderFrontStandardAboutPanelWithOptions:options];
}



そんな訳で、「ヒレガス本」P204のチャレンジ問題からかなり逸脱してしまいましたが、どうでしょうか。
 
 

2010/02/22

新Macのプログラミング入門 その2

前回引き続き「ヒレガス本第3版」からの内容です。当ブログの主たる読者のほとんどにとって全く興味のない内容と思いますが、まっ自分のブログなんで好きにさせてもらいます。

そんな訳で本日のお題は、ヒレガス本P177第11章の「Core Data入門」の例題”CarLot”です。実際にやってみられた方、うまく動作しましたか。私のMac環境、MacOSX10.6.2、Xcode3.2.1、Interface Builder3.2.1では、本編記載通りに作成すると、左の図のように写真を挿入できる”Image Well”に一種類の画像データしか挿入できず、例えば二行目のレクサスを選んでも一行目に挿入したヴォクシーの写真が表示されてしまいます。
ちなみに画像データは予め自分で用意しておいて、”Image Well”にドラッグ&ドロップして挿入します。
本編P179によれば、最初に”MyDocument.XCdatamodel”からエンティティとプロパティを定義する時に、”Photo”プロパティのデータ型を”バイナリー”にするように書いてあります。ところがこのとおりにすると、前述のとおり画像データが一種類しか挿入できなくなるようです。
対策として、”photo”のデータ型を”変換可能”に設定することで、複数の画像データが”Image Well”に挿入できるようになります。
デバッグに関しては、とりあえず「Interface Builderの設定を間違えたのとちゃうか」ということで、いろいろいじっているうちに偶然上手くいったというのが本当のところです。→いまいち理解度が低くてすみません。
で、完成したのが左の図です。これでレクサスにはレクサスの、ヴォクシーにはヴォクシーの画像データがドラッグ&ドロップで挿入できるようになりました。

しかし”Core Data”+バインドは恐るべしですね。なんだかよくわらかないうちに、入力、削除、保存、読み込み、アンドゥなど一般的な機能が全て搭載されたアプリができてしまいます。きちんと理解できている人には、強力なツールなんでしょうね。じっくり勉強せなあきませんなぁ。
 
 

2010/02/06

新Macのプログラミング入門 その1

超不人気シリーズの「Macのプログラミング入門」ですが、ブログも新しくしたことなので、気分を新たにその1からスタートします。(以前から数えるとその15です。)

二週間程前、まいけるさんと飲みに行ったついでにMacプログラミングの参考書「MacOSX Cocoaプログラミング第3版」(通称ヒレガス本)つうのを買いまして、その第6章ヘルパオブジェクトのP114にあるチャレンジ問題に挑戦したのが今回の内容です。動作は、左上の欄に記入して、”Add”ボタンを押すと、下の表(テーブル)に上から順番に挿入されていきます。「一度入力されたテーブルの内容を、ダブルクリックで編集可能にする」つうのがチャレンジ問題のポイントです。


以下にソースコードを示します。ポイントとなる編集用メソッドは本編に記載されています。実際にはこのソースコードだけでは動きません。”Interface Builder”を使っての設定が必要です。


#import

@interface AppController : NSObject {
IBOutlet NSTextField *newItemField;
IBOutlet NSTableView *toDoTableView;
NSMutableArray *items;
}

- (IBAction)addButton:(id)sender;

@end






#import "AppController.h"

@implementation AppController
//NSMutableArrayの初期化
- (id)init {
[super init];
items = [[NSMutableArray alloc] init];
return self;
}
//ボタンアクションの設定
- (IBAction)addButton:(id)sender {
NSString *string = [newItemField stringValue];
[items addObject:string];
[toDoTableView reloadData];
}
//これ以下はNSTableViewのデータソースメソッド
//データソースの行数を返す
- (int)numberOfRowsInTableView:(NSTableView *)tv {
return [items count];
}
//データソースの中身を返す
- (id)tableView:(NSTableView *)tv
objectValueForTableColumn:(NSTableColumn *)tableColumn
row:(int)row{
NSString *v = [items objectAtIndex:row];
return v;
}
//テーブル内のデータを修正する
- (void)tableView:(NSTableView *)tv
   setObjectValue:(id)anObject
   forTableColumn:(NSTableColumn *)aTableColumn
  row:(int)rowIndex {
[items replaceObjectAtIndex:rowIndex
withObject:anObject];
}

@end


最近iPhoneアプリの作成が目的で、Mac用プログラム言語であるObjective-CやそのフレームワークであるCocoaに興味を持つ方が増えてきたようです。日本語の参考書類も増えてきたんで、自称日曜プログラマーの私には喜ばしいことです。
 
 
↑ このページの先頭へ